【linux进程通信】信号的使用
来源:互联网 发布:淘宝旗舰店买手机 编辑:程序博客网 时间:2024/05/21 18:49
关于信号:
信号的作用:
1,通知进程一些特定的事件
2,强迫进程执行他自己代码中间的对信号的处理程序
进程以三种方式对一个信号作出应答:
1,显示忽略
2,执行信号相关的缺省操作
- terminate 终止
- Dump 终止并且保存信息用于调试
- Ignore 忽略
- Stop 停止,进程状态为 TASK_STOPPED
- Continue 如果进程停止,就将状态置为 TASK_RUNNING
3,调用相应的信号处理函数捕获信号(信号处理函数必须是柯重入的)
信号的分类
常规信号 前1~31号 同种类型的常规信号不需要排队接收
实时信号 POSIX标准引入 32~64位信号,需要排队以便多个信号被接受
关于信号的操作流程
*以下均有API可供查阅
- 产生信号
- 传递信号
- 执行信号的缺省操作
- 捕获信号
小例子
关于signal的用法:
函数作用,类似sigaction,改变与信号相关的操作
@signum 捕获的信号量
@sighandler_t 信号的处理函数
- SIG_IGN:忽略信号
- SIG_DFL:恢复信号的默认行为
#include <stdio.h>#include <unistd.h>/* ctrl-c 发送 SIGINT 信号给前台进程组中的所有进程。常用于终止正在运行的程序。 ctrl-z 发送 SIGTSTP 信号给前台进程组中的所有进程,常用于挂起一个进程。 ctrl-d 不是发送信号,而是表示一个特殊的二进制值,表示 EOF。 ctrl-\ 发送 SIGQUIT 信号给前台进程组中的所有进程,终止前台进程并生成 core 文件。 */void ouch(int sig){ printf("\nOUCH! - I got signal %d\n", sig); //恢复终端中断信号SIGINT的默认行为 //(void) signal(SIGINT, SIG_DFL);}void refuse(int sig){ printf("no i do not quit ! \n"); signal(SIGTSTP, SIG_DFL);}int main(){ //改变终端中断信号SIGINT的默认行为,使之执行ouch函数 //而不是终止程序的执行 (void) signal(SIGINT, ouch); //(void) signal(SIGQUIT,refuse); ctl——z 无法捕获到,不知道为什么 while(1) { printf("Hello World!\n"); sleep(1); } return 0;}
相关结构体
struct task_struct { volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ void *stack; atomic_t usage; unsigned int flags; /* per process flags, defined below */ unsigned int ptrace;#ifdef CONFIG_SMP struct llist_node wake_entry; int on_cpu;#endif int on_rq; int prio, static_prio, normal_prio; unsigned int rt_priority; const struct sched_class *sched_class; struct sched_entity se; struct sched_rt_entity rt;#ifdef CONFIG_SCHED_HMP struct ravg ravg;#endif#ifdef CONFIG_CGROUP_SCHED struct task_group *sched_task_group;#endif#ifdef CONFIG_PREEMPT_NOTIFIERS /* list of struct preempt_notifier: */ struct hlist_head preempt_notifiers;#endif /* * fpu_counter contains the number of consecutive context switches * that the FPU is used. If this is over a threshold, the lazy fpu * saving becomes unlazy to save the trap. This is an unsigned char * so that after 256 times the counter wraps and the behavior turns * lazy again; this to deal with bursty apps that only use FPU for * a short time */ unsigned char fpu_counter;#ifdef CONFIG_BLK_DEV_IO_TRACE unsigned int btrace_seq;#endif unsigned int policy; int nr_cpus_allowed; cpumask_t cpus_allowed;#ifdef CONFIG_PREEMPT_RCU int rcu_read_lock_nesting; char rcu_read_unlock_special; struct list_head rcu_node_entry;#endif /* #ifdef CONFIG_PREEMPT_RCU */#ifdef CONFIG_TREE_PREEMPT_RCU struct rcu_node *rcu_blocked_node;#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */#ifdef CONFIG_RCU_BOOST struct rt_mutex *rcu_boost_mutex;#endif /* #ifdef CONFIG_RCU_BOOST */#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) struct sched_info sched_info;#endif struct list_head tasks;#ifdef CONFIG_SMP struct plist_node pushable_tasks;#endif struct mm_struct *mm, *active_mm;#ifdef CONFIG_COMPAT_BRK unsigned brk_randomized:1;#endif#if defined(SPLIT_RSS_COUNTING) struct task_rss_stat rss_stat;#endif/* task state */ int exit_state; int exit_code, exit_signal; int pdeath_signal; /* The signal sent when the parent dies */ unsigned int jobctl; /* JOBCTL_*, siglock protected */ /* Used for emulating ABI behavior of previous Linux versions */ unsigned int personality; unsigned did_exec:1; unsigned in_execve:1; /* Tell the LSMs that the process is doing an * execve */ unsigned in_iowait:1; /* Revert to default priority/policy when forking */ unsigned sched_reset_on_fork:1; unsigned sched_contributes_to_load:1; unsigned long atomic_flags; /* Flags needing atomic access. */ pid_t pid; pid_t tgid;#ifdef CONFIG_CC_STACKPROTECTOR /* Canary value for the -fstack-protector gcc feature */ unsigned long stack_canary;#endif /* * pointers to (original) parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with * p->real_parent->pid) */ struct task_struct __rcu *real_parent; /* real parent process */ struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */ /* * children/sibling forms the list of my natural children */ struct list_head children; /* list of my children */ struct list_head sibling; /* linkage in my parent's children list */ struct task_struct *group_leader; /* threadgroup leader */ /* * ptraced is the list of tasks this task is using ptrace on. * This includes both natural children and PTRACE_ATTACH targets. * p->ptrace_entry is p's link on the p->parent->ptraced list. */ struct list_head ptraced; struct list_head ptrace_entry; /* PID/PID hash table linkage. */ struct pid_link pids[PIDTYPE_MAX]; struct list_head thread_group; struct list_head thread_node; struct completion *vfork_done; /* for vfork() */ int __user *set_child_tid; /* CLONE_CHILD_SETTID */ int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ cputime_t utime, stime, utimescaled, stimescaled; cputime_t gtime; unsigned long long cpu_power;#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE struct cputime prev_cputime;#endif#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN seqlock_t vtime_seqlock; unsigned long long vtime_snap; enum { VTIME_SLEEPING = 0, VTIME_USER, VTIME_SYS, } vtime_snap_whence;#endif unsigned long nvcsw, nivcsw; /* context switch counts */ struct timespec start_time; /* monotonic time */ struct timespec real_start_time; /* boot based time *//* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ unsigned long min_flt, maj_flt; struct task_cputime cputime_expires; struct list_head cpu_timers[3];/* process credentials */ const struct cred __rcu *real_cred; /* objective and real subjective task * credentials (COW) */ const struct cred __rcu *cred; /* effective (overridable) subjective task * credentials (COW) */ char comm[TASK_COMM_LEN]; /* executable name excluding path - access with [gs]et_task_comm (which lock it with task_lock()) - initialized normally by setup_new_exec *//* file system info */ int link_count, total_link_count;#ifdef CONFIG_SYSVIPC/* ipc stuff */ struct sysv_sem sysvsem;#endif#ifdef CONFIG_DETECT_HUNG_TASK/* hung task detection */ unsigned long last_switch_count;#endif/* CPU-specific state of this task */ struct thread_struct thread;/* filesystem information */ struct fs_struct *fs;/* open file information */ struct files_struct *files;/* namespaces */ struct nsproxy *nsproxy;/* signal handlers */ struct signal_struct *signal;//进程信号描述符 struct sighand_struct *sighand; //信号处理程序描述符 sigset_t blocked, real_blocked;//被阻塞信号的掩码,临时掩码 sigset_t saved_sigmask; /* restored if set_restore_sigmask() was used */ struct sigpending pending; //存放私有挂起信号 unsigned long sas_ss_sp; //信号处理程序备用堆栈地址 size_t sas_ss_size; //堆栈大小 int (*notifier)(void *priv); //函数指针,设备驱动用这个函数阻塞进程的某些信号 void *notifier_data;//notifier 函数的参数 sigset_t *notifier_mask;//函数所阻塞信号的位掩码 struct callback_head *task_works; struct audit_context *audit_context;#ifdef CONFIG_AUDITSYSCALL kuid_t loginuid; unsigned int sessionid;#endif struct seccomp seccomp;/* Thread group tracking */ u32 parent_exec_id; u32 self_exec_id;/* Protection of (de-)allocation: mm, files, fs, tty, keyrings, mems_allowed, * mempolicy */ spinlock_t alloc_lock; /* Protection of the PI data structures: */ raw_spinlock_t pi_lock;#ifdef CONFIG_RT_MUTEXES /* PI waiters blocked on a rt_mutex held by this task */ struct plist_head pi_waiters; /* Deadlock detection and priority inheritance handling */ struct rt_mutex_waiter *pi_blocked_on;#endif#ifdef CONFIG_DEBUG_MUTEXES /* mutex deadlock detection */ struct mutex_waiter *blocked_on;#endif#ifdef CONFIG_TRACE_IRQFLAGS unsigned int irq_events; unsigned long hardirq_enable_ip; unsigned long hardirq_disable_ip; unsigned int hardirq_enable_event; unsigned int hardirq_disable_event; int hardirqs_enabled; int hardirq_context; unsigned long softirq_disable_ip; unsigned long softirq_enable_ip; unsigned int softirq_disable_event; unsigned int softirq_enable_event; int softirqs_enabled; int softirq_context;#endif#ifdef CONFIG_LOCKDEP# define MAX_LOCK_DEPTH 48UL u64 curr_chain_key; int lockdep_depth; unsigned int lockdep_recursion; struct held_lock held_locks[MAX_LOCK_DEPTH]; gfp_t lockdep_reclaim_gfp;#endif/* journalling filesystem info */ void *journal_info;/* stacked block device info */ struct bio_list *bio_list;#ifdef CONFIG_BLOCK/* stack plugging */ struct blk_plug *plug;#endif/* VM state */ struct reclaim_state *reclaim_state; struct backing_dev_info *backing_dev_info; struct io_context *io_context; unsigned long ptrace_message; siginfo_t *last_siginfo; /* For ptrace use. */ struct task_io_accounting ioac;#if defined(CONFIG_TASK_XACCT) u64 acct_rss_mem1; /* accumulated rss usage */ u64 acct_vm_mem1; /* accumulated virtual memory usage */ cputime_t acct_timexpd; /* stime + utime since last update */#endif#ifdef CONFIG_CPUSETS nodemask_t mems_allowed; /* Protected by alloc_lock */ seqcount_t mems_allowed_seq; /* Seqence no to catch updates */ int cpuset_mem_spread_rotor; int cpuset_slab_spread_rotor;#endif#ifdef CONFIG_CGROUPS /* Control Group info protected by css_set_lock */ struct css_set __rcu *cgroups; /* cg_list protected by css_set_lock and tsk->alloc_lock */ struct list_head cg_list;#endif#ifdef CONFIG_FUTEX struct robust_list_head __user *robust_list;#ifdef CONFIG_COMPAT struct compat_robust_list_head __user *compat_robust_list;#endif struct list_head pi_state_list; struct futex_pi_state *pi_state_cache;#endif#ifdef CONFIG_PERF_EVENTS struct perf_event_context *perf_event_ctxp[perf_nr_task_contexts]; struct mutex perf_event_mutex; struct list_head perf_event_list;#endif#ifdef CONFIG_NUMA struct mempolicy *mempolicy; /* Protected by alloc_lock */ short il_next; short pref_node_fork;#endif#ifdef CONFIG_NUMA_BALANCING int numa_scan_seq; int numa_migrate_seq; unsigned int numa_scan_period; u64 node_stamp; /* migration stamp */ struct callback_head numa_work;#endif /* CONFIG_NUMA_BALANCING */ struct rcu_head rcu; /* * cache last used pipe for splice */ struct pipe_inode_info *splice_pipe; struct page_frag task_frag;#ifdef CONFIG_TASK_DELAY_ACCT struct task_delay_info *delays;#endif#ifdef CONFIG_FAULT_INJECTION int make_it_fail;#endif /* * when (nr_dirtied >= nr_dirtied_pause), it's time to call * balance_dirty_pages() for some dirty throttling pause */ int nr_dirtied; int nr_dirtied_pause; unsigned long dirty_paused_when; /* start of a write-and-pause period */#ifdef CONFIG_LATENCYTOP int latency_record_count; struct latency_record latency_record[LT_SAVECOUNT];#endif /* * time slack values; these are used to round up poll() and * select() etc timeout values. These are in nanoseconds. */ unsigned long timer_slack_ns; unsigned long default_timer_slack_ns;#ifdef CONFIG_FUNCTION_GRAPH_TRACER /* Index of current stored address in ret_stack */ int curr_ret_stack; /* Stack of return addresses for return function tracing */ struct ftrace_ret_stack *ret_stack; /* time stamp for last schedule */ unsigned long long ftrace_timestamp; /* * Number of functions that haven't been traced * because of depth overrun. */ atomic_t trace_overrun; /* Pause for the tracing */ atomic_t tracing_graph_pause;#endif#ifdef CONFIG_TRACING /* state flags for use by tracers */ unsigned long trace; /* bitmask and counter of trace recursion */ unsigned long trace_recursion;#endif /* CONFIG_TRACING */#ifdef CONFIG_MEMCG /* memcg uses this to do batch job */ struct memcg_batch_info { int do_batch; /* incremented when batch uncharge started */ struct mem_cgroup *memcg; /* target memcg of uncharge */ unsigned long nr_pages; /* uncharged usage */ unsigned long memsw_nr_pages; /* uncharged mem+swap usage */ } memcg_batch; unsigned int memcg_kmem_skip_account;#endif#ifdef CONFIG_HAVE_HW_BREAKPOINT atomic_t ptrace_bp_refcnt;#endif#ifdef CONFIG_UPROBES struct uprobe_task *utask;#endif#if defined(CONFIG_BCACHE) || defined(CONFIG_BCACHE_MODULE) unsigned int sequential_io; unsigned int sequential_io_avg;#endif};
信号描述符 signal_struct
/* * NOTE! "signal_struct" does not have its own * locking, because a shared signal_struct always * implies a shared sighand_struct, so locking * sighand_struct is always a proper superset of * the locking of signal_struct. */struct signal_struct { atomic_t sigcnt;//使用计数器 atomic_t live;//线程组中活动的进程数量 int nr_threads; struct list_head thread_head; wait_queue_head_t wait_chldexit; /* for wait4() *///在系统调用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. */ int notify_count; //在杀死整个线程组的时候使用 struct task_struct *group_exit_task;//在杀死整个线程组的时候使用 /* thread group stop support, overloads group_exit_code too */ int group_stop_count; //在 停止 整个线程组的时候使用 unsigned int flags; /* see SIGNAL_* flags below */ /* * PR_SET_CHILD_SUBREAPER marks a process, like a service * manager, to re-parent orphan (double-forking) child processes * to this process instead of 'init'. The service manager is * able to receive SIGCHLD signals and is able to investigate * the process until it calls wait(). All children of this * process will inherit a flag if they should look for a * child_subreaper process at exit. */ unsigned int is_child_subreaper:1; unsigned int has_child_subreaper:1; /* POSIX.1b Interval Timers */ int posix_timer_id; struct list_head posix_timers; /* ITIMER_REAL timer for the process */ struct hrtimer real_timer; struct pid *leader_pid; ktime_t it_real_incr; /* * ITIMER_PROF and ITIMER_VIRTUAL timers for the process, we use * CPUCLOCK_PROF and CPUCLOCK_VIRT for indexing array as these * values are defined to 0 and 1 respectively */ struct cpu_itimer it[2]; /* * Thread group totals for process CPU timers. * See thread_group_cputimer(), et al, for details. */ struct thread_group_cputimer cputimer; /* Earliest-expiration cache. */ struct task_cputime cputime_expires; struct list_head cpu_timers[3]; struct pid *tty_old_pgrp; /* boolean value for session group leader */ int leader; struct tty_struct *tty; /* NULL if no tty */#ifdef CONFIG_SCHED_AUTOGROUP struct autogroup *autogroup;#endif /* * Cumulative resource counters for dead threads in the group, * and for reaped dead child processes forked by this group. * Live threads maintain their own counters and add to these * in __exit_signal, except for the group leader. */ cputime_t utime, stime, cutime, cstime; cputime_t gtime; cputime_t cgtime;#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE struct cputime prev_cputime;#endif unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; unsigned long inblock, oublock, cinblock, coublock; unsigned long maxrss, cmaxrss; struct task_io_accounting ioac; /* * Cumulative ns of schedule CPU time fo dead threads in the * group, not including a zombie group leader, (This only differs * from jiffies_to_ns(utime + stime) if sched_clock uses something * other than jiffies.) */ unsigned long long sum_sched_runtime; /* * We don't bother to synchronize most readers of this at all, * because there is no reader checking a limit that actually needs * to get both rlim_cur and rlim_max atomically, and either one * alone is a single word that can safely be read normally. * getrlimit/setrlimit use task_lock(current->group_leader) to * protect this instead of the siglock, because they really * have no need to disable irqs. */ struct rlimit rlim[RLIM_NLIMITS];#ifdef CONFIG_BSD_PROCESS_ACCT struct pacct_struct pacct; /* per-process accounting information */#endif#ifdef CONFIG_TASKSTATS struct taskstats *stats;#endif#ifdef CONFIG_AUDIT unsigned audit_tty; unsigned audit_tty_log_passwd; struct tty_audit_buf *tty_audit_buf;#endif#ifdef CONFIG_CGROUPS /* * group_rwsem prevents new tasks from entering the threadgroup and * member tasks from exiting,a more specifically, setting of * PF_EXITING. fork and exit paths are protected with this rwsem * using threadgroup_change_begin/end(). Users which require * threadgroup to remain stable should use threadgroup_[un]lock() * which also takes care of exec path. Currently, cgroup is the * only user. */ struct rw_semaphore group_rwsem;#endif oom_flags_t oom_flags; short oom_score_adj; /* OOM kill score adjustment */ short oom_score_adj_min; /* OOM kill score adjustment min value. * Only settable by CAP_SYS_RESOURCE. */ struct mutex cred_guard_mutex; /* guard against foreign influences on * credential calculations * (notably. ptrace) */};
信号处理程序描述符:
struct sighand_struct { atomic_t count; //计数器 struct k_sigaction action[_NSIG];//在所传递的信号上执行操作的结构数组 spinlock_t siglock;//保护信号描述符和信号处理函数的描述符的自旋锁 wait_queue_head_t signalfd_wqh;};
阅读全文
0 0
- Linux 进程通信-信号的使用
- 【linux进程通信】信号的使用
- Linux进程间通信 -1使用信号
- linux之进程间通信--使用信号
- Linux进程通信--信号
- linux 进程信号通信
- linux 进程信号通信
- linux进程通信---信号
- linux进程通信-信号
- linux进程的信号通信与进程的管道通信
- linux进程间的通信(C):信号
- linux进程通信----信号的处理
- linux进程通信----信号的处理
- Linux的进程间通信(信号)
- Linux进程间的通信方式:信号
- linux进程间的通信(C):信号
- Linux C 进程间的信号通信
- 使用信号实现进程间的通信
- 写给人类的机器学习 三、无监督学习
- 前端的第一篇博客——致自己
- nlogn级别的排序算法(1)归并排序
- Vue之过渡组件的钩子函数
- 国王游戏
- 【linux进程通信】信号的使用
- 一个网址到 呈现全过程
- 获取IP地址
- C语言实现itoa
- 车牌识别之车牌定位(一)
- ios-Core Location框架
- C++11新特性
- Spring4+Hibernate5开发环境搭建过程以及遇到的问题
- em和px及其换算方法