请教xtang先生:如何在Photon界面内反复发送和接收消息?

xtang先生:
您好!
不好意思, 又要打扰您了!
对于如何在Photon界面里面反复发送和接收消息的问题我一直没有得到解决,想得到您的指点!
比如:在一个界面里面,我点击send button,通常情况下,只能发送消息一次。如果我想连续发送消息,那么我就要连续不停地按按钮,这在程序的实际应用中是不可能这样做的。我试着在sendbutton按钮的callback里面加入for(;;)死循环,这个方法在IDE里面可以行得通,可在photon界面里面按下sendbutton按钮整个界面就不动了。
另外,接收消息也只是按一下receive button接收一条消息。再按一下receivebutton整个界面都退出了。当我在receive button的callback里面加入for(;;)死循环后,当我按下receive button后,整个界面同样处于阻塞状态。
那么如何才能在一个界面内反复发送、接收消息呢?对这个问题我一直没有得到解决。 还希望得到您的指点。

开线程啊,在新的线程里做你的 for (; ; ) 不就好了吗?

xtang先生:
为什么在新的线程里面做for( ; ; )循环, 整个界面就不会处于阻塞状态了呢?
而在进程里面直接使用for( ; ; )循环,整个界面就都不动了。这是为什么呢?
前后两者之所以效果不同,其理论根据是什么呢?
对不起,xtang先生,小弟尚是一名新手,还希望能够得到您的指点。从我接触qnx之后,就一直不断地得到您的指点,这对我的学习起到了非常大的帮助,小弟非常感谢您,谢谢您!

[quote=“tragicalwind”][quote=“xtang”]开线程啊,在新的线程里做你的 for (; ; ) 不就好了吗?

xtang先生:
我在您耐心的指点下,在新的线程里使用了 for (; ; ) 。可运行的结果达不到预期的目标。我写的代码如下:

/* Standard headers */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <mqueue.h>

/* Local headers */
#include “ablibs.h”
#include “abimport.h”
#include “proto.h”

#define Q_FLAGS O_RDWR | O_CREAT
#define Q_PERM S_IRUSR | S_IWUSR | S_IROTH

int
send_msg( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo )

{
/* eliminate ‘unreferenced’ warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;

pthread_create( 0, 0, &send_msg, NULL );

pthread_create( 0, 0, &rec_msg, NULL );

return( Pt_CONTINUE );
}

void *send_msg ( void *arg)
{
char buf[100];
mqd_t qd;
struct mq_attr attr;
int i;

bzero ( buf, 100);
attr.mq_maxmsg = 100;
attr.mq_msgsize = 100;
qd = mq_open ( “/test_queue”, Q_FLAGS, Q_PERM, &attr);
if ( qd == -1 )
{
perror ( “Can not create the test_queue\n”);
//exit ( 1 );
}
else
{
strcpy ( buf, “I am a student”);
for( i = 0; i < 10; i++ )
for ( ; ; )
{
mq_send ( qd, buf, strlen ( buf ), 0 );
//sleep ( 1 );
}
}
mq_close ( qd );

}

void *rec_msg ( void *arg )
{
char buf[100];
mqd_t qd;
struct mq_attr attr;
struct sched_param thr_param;

qd = mq_open ( “/test_queue”, O_RDONLY);
if ( qd == -1 )
{
perror ( “Can not open the test_queue!\n”);
exit ( 1 );
}
else
{
while ( mq_receive ( qd, buf, 100, NULL) > 0)
{
//pritnf ( “the receive mes is: %s\n”);

     /* display the receive msg in the PtTerminal widget  */

PtTerminalPuts ( ABW_terminal, buf);
PtTerminalPuts ( ABW_terminal, “\r\n”);
sleep ( 1 );
}
}
mq_close ( qd );
}

我在send button的callback里面,创建了两个线程:send_msg() 和rec_msg ()
另外,在这个程序里面有一个PtTerminal widget,它用来显示mq_receive()接收到的消息。
我通过函数sleep ( 1 ); 目的是让mq_send ()每秒发送一条消息,mq_receive()接收一条消息.然后mq_send ()再发送一条消息,mq_receive()再接收一条消息,如此循环。
可当我加上sleep()函数运行程序后,只能在PtTerminal 里显示一到两条消息后整个程序就退出了。打印的结果是:Memory fault ( core dumped )

当我屏蔽sleep()函数后,程序运行正常,但它是在mq_send()将十条消息都发送到test_queue后,才调用mq_receive()将十条消息一起显示到PtTerminal.
xtang 先生,那么如何才能发送一条消息,接收一条消息呢?
另外,“Memory fault ( core dumped )”这个提示是什么意思呢?

xtang先生:?我要做的工作里面有许多for(; ; )循环,也要求发送一条消息,接收一条消息,所以我非常关心这些方面的问题,希望能够再次得到您耐心的指点!非常感谢!

xtang先生,期盼您在空闲的时间对我向您请教的问题给予指点好吗?
非常感谢!

xtnag先生:您好,我问您的问题您怎么不理我呢?是不是没有时间?

我一直在期盼着您的回复,您的回复对我的学习起到了非常大的帮助,所以我非常非常希望能尽快看到您给我所问的问题以指点,好吗?
谢谢您了。

Memory fault (Core dumped) 的意思是你的程序读写了非法的地址, 有一个core file通常生成在 /var/dumps/ 下面, 保存了出错时的现场, 你需要用gdb那样的调试器来检查错在那里.

至于你的程序要在for(; ; )里发送消息, 我一直觉得有疑问. 一个系统, 通常是外部事件才会引起消息传递的, 这个外部事件, 或者是用户的键盘, 鼠标输入, 或者是硬件中断, 又或者是时钟, 总的来说, 什么事件也没有就循环是实时系统的大忌.

最后, 你的关于一发一收的问题. 消息队列就是为了非同步设计的, 如果你一定需要同步, 或者你要设计自已的同步消息, 或者要改消息队列为QNX 标准的MsgSend()/Receive()/Reply(), 再或者用mutex, semaphor来进行同步.