关于TimerTimeout()的困惑

请大家帮我看下程序不知道MsgSend函数为什么无法unblock

client程序

int main
{

uint64_t timeout=1000000000;
TimerTimeout(CLOCK_REALTIME, _NTO_TIMEOUT_SEND | _NTO_TIMEOUT_REPLY,
NULL,&timeout,NULL);
int retval = MsgSend(coid,&msg,sizeof(msg),&rpmsg,sizeof(rpmsg));

}

server程序
int main()
{

for( ; ; )
{
int rcvid=MsgReceive(attach->chid, &msg, sizeof( msg ), NULL);

}

}

如果只运行client的话,MsgSend函数可被unblock,但如果先运行server然后运行client的话,MsgSend函数无法被unblock。

哦,搞错了一点。单独运行client时,由于server不存在,所以MsgSend返回错误,而不是没unblock了。TimerTimeout到底如何使用啊?难道不能这么用

如果你的server,不进行MsgReceive(),你的MsgSend()应该会返回-1,而errno会是 ETIMEDOUT。 这是 _NTO_TIMEOUT_SEND的作用。

如果你的Server进行了 MsgReceive(),那么MsgSend()后就会变成REPLY_BLOCK,按说你的 _NTO_TIMEOUT_REPLY应该也可以timeout的,但是,还有一个“UNBLOCK"的问題。 :slight_smile:

在QNX里,如果一个client进入了 REPLY_BLOCK,意味着它的消息server已经收到了,正在处理。如果这个时候client偷偷地不BLOCK,溜走了的话,会造成server的困惑。(Server要MsgReply()时对方却不在)更严重的是,如果溜走了的线程在Server进行MsgReply()前再次MsgSend()的话,Server很可能会回答错。

为了防止server的这种困惑,默认规定当一个 REPLY_BLOCK状态的线程想要不BLOCk时,内核不是自动地放它走,而是向它所在的Server发送一个”unblock pulse". Server收到这个pulse后,可以进行内部清理,然后MsgError()来放client走。所以在你的例子里,你的Server应该会收到一个unblock pulse,而由你的server来放client走。

当然,在创建channle时,也可以强行指定不需要这样的unblock pulse (_NTO_CHF_UNBLOCK in ChannelCreate())。这时,内核就不会通知server而直接让client继续了。

你MsgReceive()用的是attach->chid,所以我猜你是用的 name_attach()来建立的Channel,应该是默认需要UNBLOCK PULSE的那种。

server的MsgReceive()确实收到了pulse(返回值为0),然后可通过调用MsgError()来Unblock client。 感谢xtang的帮助