我创建了一个包含多个进程的程序,每个进程都有多个线程。我想使用ctrl-c停止程序,并决定使用中断处理程序。为此,我使用signal()函数在按下ctrl-c时设置标志。大多数线程包含没有阻塞语句的循环,只是在未设置标志时运行。设置标志后,循环结束并调用pthread_exit()。一些线程包含一个阻塞语句,可能无法达到注意到标志更改并且循环可以结束的程度。
在下面的示例中,这将导致内存泄漏(没有free()的malloc())和未正确结束的进程。
我检查了很多Q& A,但找不到合适的解决方案。任何帮助将不胜感激!
我在下面添加了一个示例(伪代码):
int flag = 0;
int main(void)
{
// when (CTRL-C) is pressed, execute the interrupt handler
signal(SIGINT, interrupt_handler_STATSERVER);
// -- THREAD1: continuously receive packets from the data server
pthread_t receivePackets_thread;
int rc = pthread_create(&receivePackets_thread, NULL,(void*) receiveFromDataServer, NULL);
if (rc)
{
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
void* receiveFromDataServer(void)
{
while(flag == 0)
{
//every loop, allocate memory for a packet
packet = (ProcessedPacket*) malloc(sizeof(ProcessedPacket));
if(packet == NULL)
{
// ERROR: mem allocation error
}
else
{
// wait for a connection
//*** THE BLOCKING STATEMENT IS HERE ***
}
}
pthread_exit(NULL);
}
void interrupt_handler_STATSERVER(int signum)
{
printf("STAT SERVER INTERRUPT!\n");
flag = 1;
}`
答案 0 :(得分:1)
确保在所有子线程上屏蔽SIGINT,因为信号传递到单个任意线程而没有屏蔽信号。这保证了您的“管理线程”将获得ctrl-c。然后,使用管理线程中的pthread_kill使用未屏蔽的信号将信号发送到其他线程。这将中断您的阻塞调用,并允许您测试标志等。
阅读本文:http://man7.org/linux/man-pages/man7/signal.7.html
特别是标题为“信号掩码和未决信号”的部分
使用pthread_sigmask检查并更改线程的信号掩码。