当前位置: 技术问答>linux和unix
线程和信号的小白问题
来源: 互联网 发布时间:2016-10-27
本文导语: 《unix环境高级编程》程序清单12.6,待会贴源码,先说说我的几个困惑。 第一,线程thr_fn的信号屏蔽字从主线程继承,继承过去的屏蔽字是不是有点像环境变量的形式?因为之前sigprocmask和sigmask函...
《unix环境高级编程》程序清单12.6,待会贴源码,先说说我的几个困惑。
第一,线程thr_fn的信号屏蔽字从主线程继承,继承过去的屏蔽字是不是有点像环境变量的形式?因为之前sigprocmask和sigmask函数最后一个参数就是保存当前的屏蔽字嘛,没有谁复制给这个参数,我就猜想是不是有点像环境继承的形式?大大们给个准确的说法吧
但是这个程序里 它使用了一个mask的全局变量,在住历程中被赋予新的屏蔽字,在线程thr_fn中他是直接拿来用的。我的问题就是如果不用全局变量,能不能在线程thr_fn中得到它,也就是上面的问题了。
第二,这里面用到了条件变量,条件变量中使用了互斥量,如果不特地设置递归互斥量的话,互斥量重复被加锁只能阻塞再次加锁的线程,但是程序里先在住历程中锁住,然后在线程thr_fn中又获得,将quitflag置1并发送pthread_cond_signal(&wait),这是咋回事啊。
第三,昨天发了个帖子问在sigprocmask在多线程中“undefined”的事,说sigprocmask在多线程中行为不确定,但是这个程序最后就用的sigprocmask回复整个进程的屏蔽字,这是咋回事啊,叫小弟怎么用怎么理解啊。。。
---------------------------------------------------------------------------------------------------
下面是代码
#include "apue.h"
#include
int quitflag; /* set nonzero by thread */
sigset_t mask;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t wait = PTHREAD_COND_INITIALIZER;
void *thr_fn(void *arg)
{
int err, signo;
for (;;)
{
err = sigwait(&mask, &signo);
if (err != 0)
err_exit(err, "sigwait failed");
switch (signo)
{
case SIGINT:
printf("ninterruptn");
break;
case SIGQUIT:
pthread_mutex_lock(&lock);
quitflag = 1;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&wait);
return(0);
default:
printf("unexpected signal %dn", signo);
exit(1);
}
}
}
int main(void)
{
int err;
sigset_t oldmask;
pthread_t tid;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGQUIT);
if ((err = pthread_sigmask(SIG_BLOCK, &mask, &oldmask)) != 0)
e rr_exit(err, "SIG_BLOCK error");
err = pthread_create(&tid, NULL, thr_fn, 0);
if (err != 0)
err_exit(err, "can't create thread");
pthread_mutex_lock(&lock);
while (quitflag == 0)
pthread_cond_wait(&wait, &lock);
pthread_mutex_unlock(&lock);
quitflag = 0;
if (sigprocmask(SIG_SETMASK, &oldmask, NULL)
第一,线程thr_fn的信号屏蔽字从主线程继承,继承过去的屏蔽字是不是有点像环境变量的形式?因为之前sigprocmask和sigmask函数最后一个参数就是保存当前的屏蔽字嘛,没有谁复制给这个参数,我就猜想是不是有点像环境继承的形式?大大们给个准确的说法吧
但是这个程序里 它使用了一个mask的全局变量,在住历程中被赋予新的屏蔽字,在线程thr_fn中他是直接拿来用的。我的问题就是如果不用全局变量,能不能在线程thr_fn中得到它,也就是上面的问题了。
第二,这里面用到了条件变量,条件变量中使用了互斥量,如果不特地设置递归互斥量的话,互斥量重复被加锁只能阻塞再次加锁的线程,但是程序里先在住历程中锁住,然后在线程thr_fn中又获得,将quitflag置1并发送pthread_cond_signal(&wait),这是咋回事啊。
第三,昨天发了个帖子问在sigprocmask在多线程中“undefined”的事,说sigprocmask在多线程中行为不确定,但是这个程序最后就用的sigprocmask回复整个进程的屏蔽字,这是咋回事啊,叫小弟怎么用怎么理解啊。。。
---------------------------------------------------------------------------------------------------
下面是代码
#include "apue.h"
#include
int quitflag; /* set nonzero by thread */
sigset_t mask;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t wait = PTHREAD_COND_INITIALIZER;
void *thr_fn(void *arg)
{
int err, signo;
for (;;)
{
err = sigwait(&mask, &signo);
if (err != 0)
err_exit(err, "sigwait failed");
switch (signo)
{
case SIGINT:
printf("ninterruptn");
break;
case SIGQUIT:
pthread_mutex_lock(&lock);
quitflag = 1;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&wait);
return(0);
default:
printf("unexpected signal %dn", signo);
exit(1);
}
}
}
int main(void)
{
int err;
sigset_t oldmask;
pthread_t tid;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGQUIT);
if ((err = pthread_sigmask(SIG_BLOCK, &mask, &oldmask)) != 0)
e rr_exit(err, "SIG_BLOCK error");
err = pthread_create(&tid, NULL, thr_fn, 0);
if (err != 0)
err_exit(err, "can't create thread");
pthread_mutex_lock(&lock);
while (quitflag == 0)
pthread_cond_wait(&wait, &lock);
pthread_mutex_unlock(&lock);
quitflag = 0;
if (sigprocmask(SIG_SETMASK, &oldmask, NULL)