在linux进程的描述中,task_struct结构体中存在下面的信号域:
- struct task_struct {
-
….
-
struct signal_struct *signal;//该进程的信号描述符指针
-
struct sighand_struct *sighand;//信号处理程序描述符
-
sigset_t blocked,real_blocked;//被阻塞信号的掩码,临时掩码
-
sigset_t saved_sigmask;//
-
struct sigpending pending;//私有信号挂起队列
-
unsigned long sas_ss_sp;//信号处理程序备用栈地址
-
size_t sas_ss_size;//信号处理程序备用栈大小
-
int (*notifier)(void *priv);//指向一个函数指针,设备驱动程序用该函数阻塞进程的某些信号
-
void *notifier_data;//处理函数的形参
-
sigset_t *notifier_mask;//设备驱动程序通过notifier函数所阻塞的信号位掩码
-
…..
-
}
-
sigset_t定义如下:
-
typedef struct {
-
unsigned long sig[2];
-
}sigset_t
信号编号中1~31为非实时信号31~64为实时信号(通过kill
-l 来查看系统中的所有信号),当系统创建的是线程时就会进行共享,其中的部分函数代码如下:
- static int copy_signal(unsigned long clone_flags,struct task_struct *tsk)
-
{
-
struct signal_struct *sig;
-
int ret;
-
if(clone_flags & CLONE_THREAD) {
-
atomic_inc(¤t->signal->count);
-
atomic_inc(¤t->signal->live);
-
return 0;
-
}
-
…......
-
}
struct
signal_struct 结构体的定义如下:
- struct signal_struct {
-
atomic_t count;//信号描述符的使用计数器
-
atomic_t live;//线程组中的活动进程数量
-
wait_queue_head_t wait_chldexit;//wait4()中睡眠的进程等待队列
-
struct task_struct *curr_target;//接收信号的线程组中最后一个进程的描述符
-
struct sigpending shared_pending;//存放共享挂起信号的数据结构
-
int group_exit_code;//线程组的进程终止代码
-
struct task_struct *group_exit_task;//杀死整个线程组
-
int notify_count;//杀死整个线程组时使用
-
int group_stop_count;//停止整个线程组
-
unsigned int flags;//在传递修改进程状态的信号使用的标志
-
…......
-
};
信号处理函数
- struct sighand_struct {
-
atomic_t count;
-
struct k_sigaction action[64];//与信号的个数保持一致
-
spinlock_t siglock;//保护信号描述符和信号处理程序描述符的自旋锁
-
wait_queue_head_t signalfd_wqh;
-
};
struct
k_sigaction的原型如下:
- struct k_sigaction {
-
struct sigaction sa;
-
}
-
struct sigaction{
-
__sighandler_t sa_handler;//处理函数指针或SIG_DFL或SIG_IGN
-
unsigned long sa_flags;//处理信号的标志
-
__sigrestore_t sa_restorer;//目前已不再使用
-
sigset_t mask;//当前信号处理程序时要屏蔽的信号
-
}
挂起信号队列为:
- struct sigpending {
-
struct list_head list;
-
sigset_t signal;
-
}
一共有两条信号挂起队列:公有信号挂起队列和私有信号挂起队列,实时信号排队的数据结构如下:
- struct sigqueue
-
{
-
struct list_head list;
-
int flags;//sigqueue数据结构标志
-
siginfo_t info;//产生信号的事件
-
struct user_struct *user;//与信号相关进程的用户信息
-
si_signo;//信号编号
-
si_errno;//引起信号产生的指令出错码
-
si_code;//发送信号者的代码
-
}
同样当创建线程时也会共享线程处理函数:
- ….
-
if(clone_flags & (CLONE_SIGHAND | CLONE_THREAD)) {
-
atomic_inc(¤t->sighand->count);
-
return 0;
-
}
-
…..
阅读(1730) | 评论(0) | 转发(0) |