线程和信号
信号十分复杂, 在本身进程基础上, 就存在信号处理. 信号屏蔽字. 信号未决等因素需要去考虑, 在遇到线程后, 信号与线程之间就更是复杂
基础认知
每个线程都有自己的信号屏蔽字, 但是信号的处理是进程中所有线程共享的, 这就意味着单个线程可以阻止某些信号, 但当某个线程修改了与某个信号相关的处理行为后, 所有的线程都必须共享这个行为的改变.
进程中的信号是递送到单个线程的。如果一个信号与硬件故障相关,那么该信号一般会被发送到引起该事件的线程去, 而其他的信号则会被发送到任意一个线程去.
线程信号操作
是否还记得之前的sigpromask函数, 此函数只能用于单线程函数, 因为它会设置errno这个全局变量. 其实许多函数都是不允许在多线程情况下执行的, 他们都被称为不可重入函数. 大多数情况下,linux都提供了他们对应的可重入版本
在线程中想要设置信号屏蔽字需要通过 pthread_sigmask
线程能通过sigwait来等待一个或多个信号的出现
如果信号集中的某个信号在sigwait调用的时候处于挂起状态, 那么sigwait将会无阻塞的返回. 在返回前, sigwait将从进程中移除那些处于挂起等待状态的信号.
为了避免错误行为的发生,线程在调用sigwait之前, 必须阻塞那些它正在等待的信号(即在调用sigwait之前将需要接收的信号阻塞),sigwait会在有要等待的信号被递送来之前,原子的取消信号的阻塞状态.接收到信号后,即在返回之前, sigwait还会恢复线程的信号屏蔽字
为了防止信号中断某个线程的正常执行, 我们还可以把要接收的信号添加到每个线程的信号屏蔽字中,然后安排专用线程处理信号.
进程之间的信号传递通过kill, 线程之间的信号传递也类似:
信号十分复杂, 在本身进程基础上, 就存在信号处理. 信号屏蔽字. 信号未决等因素需要去考虑, 在遇到线程后, 信号与线程之间就更是复杂
基础认知
每个线程都有自己的信号屏蔽字, 但是信号的处理是进程中所有线程共享的, 这就意味着单个线程可以阻止某些信号, 但当某个线程修改了与某个信号相关的处理行为后, 所有的线程都必须共享这个行为的改变.
进程中的信号是递送到单个线程的。如果一个信号与硬件故障相关,那么该信号一般会被发送到引起该事件的线程去, 而其他的信号则会被发送到任意一个线程去.
线程信号操作
是否还记得之前的sigpromask函数, 此函数只能用于单线程函数, 因为它会设置errno这个全局变量. 其实许多函数都是不允许在多线程情况下执行的, 他们都被称为不可重入函数. 大多数情况下,linux都提供了他们对应的可重入版本
在线程中想要设置信号屏蔽字需要通过 pthread_sigmask
int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);
用法与sigprocmask大致类似, 不需多言
线程能通过sigwait来等待一个或多个信号的出现
int sigwait(const sigset_t *set, int *sig);
set指定了线程等待的信号集, sig指向的整数表示接收到的信号值
如果信号集中的某个信号在sigwait调用的时候处于挂起状态, 那么sigwait将会无阻塞的返回. 在返回前, sigwait将从进程中移除那些处于挂起等待状态的信号.
为了避免错误行为的发生,线程在调用sigwait之前, 必须阻塞那些它正在等待的信号(即在调用sigwait之前将需要接收的信号阻塞),sigwait会在有要等待的信号被递送来之前,原子的取消信号的阻塞状态.接收到信号后,即在返回之前, sigwait还会恢复线程的信号屏蔽字
为了防止信号中断某个线程的正常执行, 我们还可以把要接收的信号添加到每个线程的信号屏蔽字中,然后安排专用线程处理信号.
进程之间的信号传递通过kill, 线程之间的信号传递也类似:
int pthread_kill(pthread_t thread, int sig);