gpt4 book ai didi

multithreading - Posix 线程 :Signal a thread that is running in while loop

转载 作者:行者123 更新时间:2023-12-04 06:43:35 26 4
gpt4 key购买 nike

我有一个非常简单的线程:它向服务器发送保持事件的数据包,然后休眠。我希望我的主线程向线程发出退出信号,但每当我调用 pthread_kill() 时,它似乎都会使我的进程崩溃。

我试图在我的 while 循环开始时调用 sigpending(),然后调用 sigismember(),但我认为它崩溃了,因为它不知道有任何处理信号的句柄(我使用的是 sigaddset( ) 在 while 循环之前),如下所示:

void* foo(void* arg)
{
sigset_t set, isSignal;

sigemptyset(&set);
if (sigaddset(&set, SIGUSR1) == -1) { /* ... */ }

while (1) {
if (sigpending(&isSignal) != 0) { /* .. */ }
else if (sigismember(&isSignal, SIGUSR1)) {
break;
}

sendKeepAlive();
sleep(SECONDS);
}
return NULL;
}

似乎是 pthread_kill(pth, SIGUSR1);使程序死亡。请问发送信号的正确方法是什么?我应该改用 pthread_sigmask() 吗?

最佳答案

当信号由操作系统传送时处于挂起状态,但进程或线程已阻止它。如果您没有阻止 SIGUSR1,那么它将被传送,并且 SIGUSR1 的默认配置是终止进程。在这种情况下,您的 sigpending 什么都不做;它被有效地绕过了。首先使用 pthread_sigmask 阻止 SIGUSR1 或(可选)处理它。

总的来说,这是一个可疑的设计。使用阻塞/信号挂起代码,根据 SECONDS 设置的时间长短,您仍然可以等待很长时间,然后线程循环发现是时候关闭了。如果你真的想为此使用信号,我建议建立一个设置开关的信号处理程序。当 SIGUSR1 被传递时,处理程序将被调用,它设置开关,sleep 将被信号中断,您检查 EINTR 并立即循环检查开关,然后 pthread_exit.

选项1(在linux上编译)

#define _POSIX_C_SOURCE 2

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <signal.h>

void* foo(void* arg)
{
sigset_t set, isSignal, allSigs;

sigfillset(&allSigs);

if (sigprocmask(SIG_SETMASK, &allSigs, NULL) == -1)
{
printf("sigprocmask: %m\n");
exit(1);
}

sigemptyset(&set);

if (sigaddset(&set, SIGUSR1) == -1)
{
printf("sigaddset: %m\n");
exit(1);
}

while (1)
{
if (sigpending(&isSignal) != 0)
{
printf("sigpending: %m\n");
exit(1);
}
else
if (sigismember(&isSignal, SIGUSR1))
{
printf("signal pending for thread, exiting\n");
break;
}

printf("Doing groovy thread stuff...\n");

sleep(2);
}

return NULL;
}


int main(int argc, char *argv[])
{
pthread_t tid;
int rc;

rc = pthread_create(&tid, NULL, foo, NULL);

if (rc)
{
printf("pthread_create: %m\n");
exit(1);
}

sleep(10);

pthread_kill(tid, SIGUSR1);

pthread_join(tid, NULL);

}

选项 2(在 linux 上编译)

#define _POSIX_C_SOURCE 2

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <signal.h>

volatile int stop = 0;

void handler(int sig)
{
stop = 1;
}

void* foo(void* arg)
{
signal(SIGUSR1, handler); //use sigaction, i'm too lazy here

while (! stop)
{
printf("Doing groovy thread stuff...\n");

if (sleep(4) > 0)
if (errno == EINTR)
{
printf("sleep interrupted, exiting thread...\n");
continue;
}
}

return NULL;
}


int main(int argc, char *argv[])
{
pthread_t tid;
int rc;

rc = pthread_create(&tid, NULL, foo, NULL);

if (rc)
{
printf("pthread_create: %m\n");
exit(1);
}

sleep(10);

pthread_kill(tid, SIGUSR1);

pthread_join(tid, NULL);

}

选项 3 如果可以,请使用其他机制。建议。

关于multithreading - Posix 线程 :Signal a thread that is running in while loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17606821/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com