C 在pthread_kill()中使用SIGUSR1和SIGUSR2作为信号
我想使用SIGUSR1和SIGUSR2作为pthread_kill()的参数,以挂起正在运行的线程的执行(即线程向自身发送信号),并在满足条件时由对等线程恢复挂起的线程。 对于任何诸如示例代码或有关它的视图之类的指针,我都非常感激C 在pthread_kill()中使用SIGUSR1和SIGUSR2作为信号,c,linux,pthreads,C,Linux,Pthreads,我想使用SIGUSR1和SIGUSR2作为pthread_kill()的参数,以挂起正在运行的线程的执行(即线程向自身发送信号),并在满足条件时由对等线程恢复挂起的线程。 对于任何诸如示例代码或有关它的视图之类的指针,我都非常感激 谢谢虽然我同意Nemo的观点,但是有一些通过信号暂停线程的有效用例。PWPT中的susp.c代码当然是一个很好的基础,但您也可以在中找到它。您可能还希望中断阻塞IO系统调用的线程(请参阅)或中断信号量等待(请参阅)。信令用作以下示例。然而,在您的情况下,您需要条件变量
谢谢虽然我同意Nemo的观点,但是有一些通过信号暂停线程的有效用例。PWPT中的
susp.c
代码当然是一个很好的基础,但您也可以在中找到它。您可能还希望中断阻塞IO系统调用的线程(请参阅)或中断信号量等待(请参阅)。信令用作以下示例。然而,在您的情况下,您需要条件变量
他有一个例子
pthread_cond_wait (condition,mutex)
pthread_cond_signal (condition)
pthread_cond_broadcast (condition)
下面演示了正确使用带有pthread_kill()的信号的示例
/* ptsig.c
This program illustrates the use of signals in threads.
Three threads including the main thread.
main thread
a. Set up a signal mask to block all signals.
b. Set up signal handlers for SIGINT and SIGUSR1.
c. Create thread_1, detached.
d. Create thread_2, nondetached.
e. Send SIGINT & SIGUSR1 to thread_1.
f. Quit.
thread_1
a. Unblock all to embrace all signals.
b. Wait for signals.
c. Send SIGINT and SIGUSR1 to thread_2
d. Wait for thread_2 to terminate
e. Print thread_2 return status.
f. Quit
thread_2
a. Unblock SIGUSR1 -- all others blocked due to inheritance.
b. Wait for signals.
c. Quit
Note: There is hardly any error checking in this example -- not a good
idea, but to make the program a bit more easier to explain.
To compile: gcc ptsig.c -lpthread
Sam Hsu (11/19/10)
*/
#define _POSIX_C_SOURCE 199506L
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
pthread_t tid2;
static void int_handler(int signo), usr1_handler(int signo);
void millisleep(int milliseconds)
{
usleep(milliseconds * 1000);
}
main()
{
pthread_t tid1;
pthread_attr_t attr_obj; /* a thread attribute variable */
void *thread_1(void *), *thread_2(void *);
sigset_t sigmask;
struct sigaction action;
/* set up signal mask to block all in main thread */
sigfillset(&sigmask); /* to turn on all bits */
pthread_sigmask(SIG_BLOCK, &sigmask, (sigset_t *)0);
/* set up signal handlers for SIGINT & SIGUSR1 */
action.sa_flags = 0;
action.sa_handler = int_handler;
sigaction(SIGINT, &action, (struct sigaction *)0);
action.sa_handler = usr1_handler;
sigaction(SIGUSR1, &action, (struct sigaction *)0);
pthread_attr_init(&attr_obj); /* init it to default */
pthread_attr_setdetachstate(&attr_obj, PTHREAD_CREATE_DETACHED);
pthread_create(&tid1, &attr_obj, thread_1, (void *)NULL);
printf("TID(%u) created\n", (unsigned int)tid1);
pthread_attr_setdetachstate(&attr_obj, PTHREAD_CREATE_JOINABLE);
pthread_create(&tid2, &attr_obj, thread_2, (void *)NULL);
printf("TID(%u) created\n", (unsigned int)tid2);
millisleep(1000); /* for some reason a sleep is needed here */
printf("main(%u) sending SIGINT to TID(%u)\n", (unsigned int)pthread_self(), (unsigned int)tid1);
pthread_kill(tid1, SIGINT); /* not blocked by tid1 */
printf("main(%u) sending SIGUSR1 to TID(%u)\n", (unsigned int)pthread_self(), (unsigned int)tid1);
pthread_kill(tid1, SIGUSR1); /* not blocked by tid1 */
printf("main(%u) is terminating\n", (unsigned int)pthread_self());
pthread_exit((void *)NULL); /* will not terminate process */
} /* main */
void *thread_1(void *dummy)
{
int sig, status, *status_ptr = &status;
sigset_t sigmask;
sigfillset(&sigmask); /* will unblock all signals */
pthread_sigmask(SIG_UNBLOCK, &sigmask, (sigset_t *)0);
sigwait(&sigmask, &sig);
switch(sig) {
case SIGINT:
int_handler(sig);
break;
default:
break;
}
printf("TID(%u) sending SIGINT to %u\n", (unsigned int)pthread_self(), (unsigned int)tid2);
pthread_kill(tid2, SIGINT); /* blocked by tid2 */
printf("TID(%u) sending SIGUSR1 to %u\n", (unsigned int)pthread_self(), (unsigned int)tid2);
pthread_kill(tid2, SIGUSR1); /* not blocked by tid2 */
pthread_join(tid2, (void **)status_ptr);
printf("TID(%u) exit status = %d\n", (unsigned int)tid2, status);
printf("TID(%u) is terminating\n", (unsigned int)pthread_self());
pthread_exit((void *)NULL); /* calling thread will terminate */
} /* thread_1 */
void *thread_2(void *dummy)
{
int sig;
sigset_t sigmask;
sigemptyset(&sigmask); /* to zero out all bits */
sigaddset(&sigmask, SIGUSR1); /* to unblock SIGUSR1 */
pthread_sigmask(SIG_UNBLOCK, &sigmask, (sigset_t *)0);
sigwait(&sigmask, &sig);
switch(sig) {
case SIGUSR1:
usr1_handler(sig);
break;
default:
break;
}
printf("TID(%u) is terminating\n", (unsigned int)pthread_self());
pthread_exit((void *)NULL); /* calling thread will terminate */
} /* thread_2 */
static void int_handler(int dummy)
{
printf("SIGINT received by TID(%u)\n", (unsigned int)pthread_self());
} /* int_handler */
static void usr1_handler(int dummy)
{
printf("SIGUSR1 received by TID(%u)\n", (unsigned int)pthread_self());
} /* usr1_handler */
/*ptsig.c
这个程序演示了线程中信号的使用。
包括主线程在内的三个线程。
主线
A.设置一个信号屏蔽以屏蔽所有信号。
B为SIGINT和SIGUSR1设置信号处理程序。
C创建线程_1,分离。
D创建线程2,未详细说明。
E将SIGINT和SIGUSR1发送到线程_1。
F退出
螺纹1
A.解除所有阻塞以接受所有信号。
B等待信号。
C将SIGINT和SIGUSR1发送到线程_2
D等待线程2终止
E打印线程2返回状态。
F退出
螺纹2
A.解除阻止SIGUSR1--由于继承而被阻止的所有其他文件。
B等待信号。
C退出
注意:在这个示例中几乎没有任何错误检查——这不是一个好方法
想法,但要让程序更容易解释。
编译:gcc ptsig.c-lpthread
许三明(11/19/10)
*/
#定义POSIX_C_SOURCE199506L
#包括
#包括
#包括
#包括
pthread_t tid2;
静态void int_处理程序(int signo)、usr1_处理程序(int signo);
无效毫秒睡眠(整数毫秒)
{
usleep(毫秒*1000);
}
main()
{
pthread_t tid1;
pthread_attr_t attr_obj;/*线程属性变量*/
空心*螺纹1(空心*),*螺纹2(空心*);
sigset_t sigsmask;
结构动作;
/*设置信号掩码以阻止所有主线程*/
sigfillset(&sigmask);/*打开所有位*/
pthread_sigmask(SIG_块和sigmask,(sigset_t*)0);
/*为SIGINT和SIGUSR1设置信号处理程序*/
action.sa_标志=0;
action.sa_handler=int_handler;
sigaction(SIGINT,&action,(struct-sigaction*)0;
action.sa_handler=usr1_handler;
sigaction(SIGUSR1,&action,(struct-sigaction*)0;
pthread_attr_init(&attr_obj);/*将其初始化为默认值*/
pthread_attr_setdetachstate(&attr_obj,pthread_CREATE_detachstate);
pthread_create(&tid1,&attr_obj,thread_1,(void*)NULL);
printf(“TID(%u)已创建\n”,(unsigned int)tid1);
pthread_attr_setdetachstate(&attr_obj,pthread_CREATE_JOINABLE);
pthread_create(&tid2,&attr_obj,thread_2,(void*)NULL);
printf(“TID(%u)已创建\n”,(unsigned int)tid2);
MillSleep(1000);/*出于某种原因,这里需要睡眠*/
printf(“main(%u)向TID(%u)\n)发送SIGINT,(unsigned int)pthread_self(),(unsigned int)tid1);
pthread_kill(tid1,SIGINT);/*未被tid1阻止*/
printf(“main(%u)将SIGUSR1发送到TID(%u)\n”,(unsigned int)pthread_self(),(unsigned int)tid1);
pthread_kill(tid1,SIGUSR1);/*未被tid1阻止*/
printf(“main(%u)正在终止”;(unsigned int)pthread_self();
pthread_exit((void*)NULL);/*将不会终止进程*/
}/*主要*/
空心*螺纹_1(空心*虚拟)
{
int sig,status,*status_ptr=&status;
sigset_t sigsmask;
sigfillset(&sigmask);/*将取消阻止所有信号*/
pthread_sigmask(SIG_UNBLOCK,&sigmask,(sigset_t*)0;
sigwait(&sigmask,&sig);
开关(sig){
案例信号:
内部处理器(sig);
打破
违约:
打破
}
printf(“TID(%u)将SIGINT发送到%u\n”,(unsigned int)pthread_self(),(unsigned int)tid2);
pthread_kill(tid2,SIGINT);/*被tid2阻止*/
printf(“TID(%u)将SIGUSR1发送到%u\n”,(unsigned int)pthread_self(),(unsigned int)tid2);
pthread_kill(tid2,SIGUSR1);/*未被tid2阻止*/
pthread_join(tid2,(void**)状态_ptr);
printf(“TID(%u)退出状态=%d\n”,(unsigned int)tid2,状态);
printf(“TID(%u)正在终止”;(unsigned int)pthread_self();
pthread_exit((void*)NULL);/*调用线程将终止*/
}/*螺纹1*/
空心*螺纹2(空心*虚拟)
{
int-sig;
sigset_t sigsmask;
SIGEPTYSET(&sigmask);/*将所有位归零*/
sigaddset(&sigmask,SIGUSR1);/*用于取消阻止SIGUSR1*/
pthread_sigmask(SIG_UNBLOCK,&sigmask,(sigset_t*)0;
sigwait(&sigmask,&sig);
开关(sig){
案例SIGUSR1:
usr1_处理器(sig);
打破
违约:
打破
}
printf(“TID(%u)正在终止”;(unsigned int)pthread_self();
pthread_exit((void*)NULL);/*调用线程将终止*/
}/*螺纹2*/
静态void int_处理程序(int-dummy)
{
printf(“TID(%u)\n)接收的SIGINT,(unsigned int)pthread_self());
}/*整数处理器*/
静态无效usr1_处理程序(int-dummy)
{
printf(“TID(%u)\n)收到的SIGUSR1,(unsigned int)pthread_self());
}/*usr1\U处理器*/
pthread\u cancel()比pthread\u kill()更安全。
下面是pthread\u cancel()的示例
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
static void *
thread_func(void *ignored_argument)
{
int s;
s = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
if (s != 0)
handle_error_en(s, "pthread_setcancelstate");
while (1) {
printf("sleeping\n");
sleep(1); /* Should get canceled while we sleep */
}
/* sleep() is a cancellation point */
/* Should never get here */
printf("thread_func(): not canceled!\n");
return NULL;
}
int
main(void)
{
pthread_t thr;
void *res;
int s;
/* Start a thread and then send it a cancellation request */
s = pthread_create(&thr, NULL, &thread_func, NULL);
if (s != 0)
handle_error_en(s, "pthread_create");
sleep(10); /* Give thread a chance to get started */
printf("main(): sending cancellation request\n");
s = pthread_cancel(thr);
if (s != 0)
handle_error_en(s, "pthread_cancel");
/* Join with thread to see what its exit status was */
s = pthread_join(thr, &res);
if (s != 0)
handle_error_en(s, "pthread_join");
if (res == PTHREAD_CANCELED)
printf("main(): thread was canceled\n");
else
printf("main(): thread wasn't canceled (shouldn't happen!)\n");
exit(EXIT_SUCCESS);
}
#包括
#包括
#包括
#包括
#包括
#定义句柄\u错误\u en(en,msg)\
do{errno=en;perror(msg);exit(exit_FAILURE);}while(0)
静态空隙*
线程函数(无效*忽略参数)
{
int-s;
s=pthread_setca