MQ C API - 如何在多线程环境中中止等待的“MQGET”
MQ C API - how to abort a waiting `MQGET` in a multithreaded environment
我在多线程应用程序中使用 MQ C API,其中多个工作线程通过在循环中调用 MQGET
来处理来自其自己队列的传入消息(使用 MQGMO_WAIT
设置和等待间隔 MQWI_UNLIMITED
).
它可以工作,但我找不到关闭工作线程的干净方法。如果我在另一个线程中调用 MQDISC
或 MQCLOSE
,只要有未完成的 MQGET
调用,它就会阻塞。
目前我最好的解决方案是使用 5000
的有限等待间隔而不是 MQWI_UNLIMITED
,这样 MQGET
每 5 秒调用一次 return,给出应用程序关闭的机会。但此解决方案效率较低(工作线程每 5 秒唤醒一次),并且应用最多需要 5 秒才能关闭。
使用本机终止线程 OS API 听起来不是一个好的解决方案。
所以问题是 - 当等待间隔为 MQWI_UNLIMITED
时,是否有任何方法可以完全中止等待 MQGET
?
OS是WindowsServer 2012 x64,MQ服务器版本是7.0.0.19.
使用 MQCallBack 调用而不是 MQGET。
一个选项是如果您禁用从队列中获取(即 ALTER QLOCAL(xxx) GET(DISABLED)),任何等待的 getter 将立即被丢弃,原因为 MQRC_GET_INHIBITED.
已经给出的两个答案都是不错的选择,我还有第三个要添加,所以这里是完整列表。
- 你至少是在V7上,所以你可以使用回调机制,MQCB和回调函数,然后你可以使用MQCTL挂起或停止连接。
- 使用管理命令,或在另一个线程上使用 MQSET 调用,将队列更改为 GET(DISABLED),这将唤醒 MQGET-wait MQRC_GET_INHIBITED。
- 从另一个线程 MQPUT(1) 向 MQGET 正在等待的队列发送消息。确保您的获取代码理解此消息的 format/content 表示 "time to end the app".
所有这些都同样有效,但需要对您当前的应用程序进行不同程度的更改,并且只有您知道在您的代码中哪个最简单。
我在多线程应用程序中使用 MQ C API,其中多个工作线程通过在循环中调用 MQGET
来处理来自其自己队列的传入消息(使用 MQGMO_WAIT
设置和等待间隔 MQWI_UNLIMITED
).
它可以工作,但我找不到关闭工作线程的干净方法。如果我在另一个线程中调用 MQDISC
或 MQCLOSE
,只要有未完成的 MQGET
调用,它就会阻塞。
目前我最好的解决方案是使用 5000
的有限等待间隔而不是 MQWI_UNLIMITED
,这样 MQGET
每 5 秒调用一次 return,给出应用程序关闭的机会。但此解决方案效率较低(工作线程每 5 秒唤醒一次),并且应用最多需要 5 秒才能关闭。
使用本机终止线程 OS API 听起来不是一个好的解决方案。
所以问题是 - 当等待间隔为 MQWI_UNLIMITED
时,是否有任何方法可以完全中止等待 MQGET
?
OS是WindowsServer 2012 x64,MQ服务器版本是7.0.0.19.
使用 MQCallBack 调用而不是 MQGET。
一个选项是如果您禁用从队列中获取(即 ALTER QLOCAL(xxx) GET(DISABLED)),任何等待的 getter 将立即被丢弃,原因为 MQRC_GET_INHIBITED.
已经给出的两个答案都是不错的选择,我还有第三个要添加,所以这里是完整列表。
- 你至少是在V7上,所以你可以使用回调机制,MQCB和回调函数,然后你可以使用MQCTL挂起或停止连接。
- 使用管理命令,或在另一个线程上使用 MQSET 调用,将队列更改为 GET(DISABLED),这将唤醒 MQGET-wait MQRC_GET_INHIBITED。
- 从另一个线程 MQPUT(1) 向 MQGET 正在等待的队列发送消息。确保您的获取代码理解此消息的 format/content 表示 "time to end the app".
所有这些都同样有效,但需要对您当前的应用程序进行不同程度的更改,并且只有您知道在您的代码中哪个最简单。