- UID
- 1029342
- 性别
- 男
|
信号是操作系统中一种很重要的通信方式.近几个版本中,信号处理这部份很少有大的变动.我们从用户空间的信号应用来分析Linux内核的信号实现方式.
一:信号有关的数据结构
在task_struct中有关的信号结构:
struct task_struct {
……
//指向进程信号描述符
struct signal_struct *signal;
//指向信号的处理描述符
struct sighand_struct *sighand;
//阻塞信号的掩码
sigset_t blocked, real_blocked;
//保存的信号掩码.当定义TIF_RESTORE_SIGMASK的时候,恢复信号掩码
sigset_t saved_sigmask; /* To be restored with TIF_RESTORE_SIGMASK */
//存放挂起的信号
struct sigpending pending;
//指定信号处理程序的栈地址
unsigned long sas_ss_sp;
//信号处理程序的栈大小
size_t sas_ss_size;
//反映向一个函数的指针,设备驱动用此来阻塞进程的某些信号
int (*notifier)(void *priv);
//notifier()的参数
void *notifier_data;
//驱动程序通过notifier()所阻塞信号的位图
sigset_t *notifier_mask;
……
}
Sigset_t的数据结构如下:
//信号位图.
typedef struct {
//在x86中需要64位掩码,即2元素的32位数组
unsigned long sig[_NSIG_WORDS];
} sigset_t;
#define _NSIG 64
#ifdef __i386__
# define _NSIG_BPW 32
#else
# define _NSIG_BPW 64
#endif
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
在linux中共有64个信号.前32个为常规信号.后32个为实时信号.实时信号与常规信号的唯一区别就是实时信号会排队等候.
struct sigpending结构如下:
//信号等待队列
struct sigpending {
struct list_head list;
//如果某信号在等待,则该信号表示的位置1
sigset_t signal;
};
Struct sighand_struct的结构如下:
struct sighand_struct {
//引用计数
atomic_t count;
//信号向量表
struct k_sigaction action[_NSIG];
spinlock_t siglock;
wait_queue_head_t signalfd_wqh;
}
同中断处理一样,每一个信号都对应action中的一个处理函数.
struct k_sigaction结构如下示:
struct sigaction {
//信号处理函数
__sighandler_t sa_handler;
//指定的信号处理标志
unsigned long sa_flags;
__sigrestore_t sa_restorer;
//在运行处理信号的时候要屏弊的信号
sigset_t sa_mask; /* mask last for extensibility */
};
Struct signal_struct结构如下:
struct signal_struct {
//共享计数
atomic_t count;
//线程组内存活的信号
atomic_t live;
//wait_chldexit:子进程的等待队列
wait_queue_head_t wait_chldexit; /* for wait4() */
/* current thread group signal load-balancing target: */
//线程组内最使收到信号的进程
struct task_struct *curr_target;
/* shared signal handling: */
//共享信号的等待队列
struct sigpending shared_pending;
/* thread group exit support */
//线程组的终止码
int group_exit_code;
/* overloaded:
* - notify group_exit_task when ->count is equal to notify_count
* - everyone except group_exit_task is stopped during signal delivery
* of fatal signals, group_exit_task processes the signal.
*/
//当kill 掉整个线程组的时候使用
struct task_struct *group_exit_task;
//当kill 掉整个线程组的时候使用
int notify_count;
/* thread group stop support, overloads group_exit_code too */
//当整个线程组停止的时候使用
int group_stop_count;
unsigned int flags; /* see SIGNAL_* flags below */
……
} |
|