我在我的代码中使用czmq和zmq库.我SIGINT通过调用signalmain 注册了一个信号处理程序.代码如下所示:
#include "czmq.h"
void sig_int(int signal);
void* pub_handler(){
zctx_t *context = zctx_new ();
void *publisher = zsocket_new (context, ZMQ_PUB);
zsocket_connect (publisher, "tcp://localhost:5555");
sleep(1);
char topic[20] = "REQ: speedlimit";
// while (true)
{
sleep( randof(10) );
zstr_sendm (publisher, topic);
zstr_send (publisher, "driver analysis data");
}
zctx_destroy (&context);
}
void* sub_handler(){
zctx_t *context = zctx_new();
void *subscriber = zsocket_new (context, ZMQ_SUB);
zsocket_connect (subscriber, "tcp://localhost:5557");
srandom ((unsigned) time (NULL));
char subscription [20] = "RESP: speedlimit" ;
zsocket_set_subscribe (subscriber, subscription);
while (true) {
char *topic = zstr_recv (subscriber);
if(!topic)
break;
char *data = zstr_recv (subscriber);
assert (streq (topic, subscription));
puts (topic);
puts (data);
free (topic);
free (data);
}
zctx_destroy (&context);
}
int main(int argc, const char *argv[])
{
pthread_t pub_id, sub_id;
signal (SIGINT, sig_int);
pthread_create(&pub_id, NULL, pub_handler, NULL);
pthread_create(&sub_id, NULL, sub_handler, NULL);
pthread_join(pub_id, NULL);
pthread_join(sub_id, NULL);
return 0;
}
void sig_int(int signal){
printf (" Interrupted\n");
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
编译为gcc -o app app.c -lpthread -lczmq -lzmq.
ctrl+c给出中断时,上面的代码不会进入信号处理程序.
czmq或zmq库有什么问题以及如何处理?
zctx的文档说它zctx为SIGINT和设置了自己的信号处理程序SIGTERM,可能会覆盖你的信号处理程序.
设置信号(SIGINT和SIGTERM)处理,以便当用户按下Ctrl-C时,将返回阻塞调用,如zmq_recv()和zmq_poll().
它还说zctx赞成使用zsock,根据其文档似乎没有设置信号处理程序.所以我的第一个建议是使用新的zsock套接字API.
但是,在这两种情况下,您似乎也可以调用zsys_handler_set(NULL);(此处记录)来显式禁用CZMQ中的默认SIGINT/SIGTERM处理.
PS:printf不是异步信号安全的,这意味着它不应该用在信号处理程序中.请参阅此处获取POSIX中的异步信号安全功能列表.