信号

信号
使用kill -l可以查看Linux支持的信号,信号用于进程间状态通知,传递简单信息。
# kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
kill命令调用kill系统调用发送信号。
NAME
kill - send signal to a process
SYNOPSIS
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
kill的实现定义在"kernel/signal.c"。信号会被缓存到进程上的一个队列上,这个队列的长
度通过ulmit控制。
# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited

pending signals (-i) 30513
kill在放入队列后,对进程做一个标记TIF_SIGPENDING,然后返回。在进程中断或系
统调用返回的时候后会检查这个标记,并作信号处理。和调度切换一样的做法。
实际上信号的行为类似一个中断,可以理解为一种软中断。程序可能在任何位置被打断,
所以信号处理函数内的操作要十分谨慎。
如果你用kill发送信号,它是作用于整个进程的,有线程都可能会处理这个信号,但只
会处理一次,这个意思是,哪个线程先走到了TIF_SIGPENDING的检查点,哪个就处理了这
个信号。
如果想给指定的线程发送信号,就需要使用tgkill这个系统调用。它也是pthread_kill的底
层函数。

 

共享内存
线程间内存是共享的,共享内存是一种使进程间可以共用一段物理内存的机制。
shmget(2)系统调用创建一段共享内存,返回一个id——shmid,shmid在系统内全局存在。
进程把shmid传入shmat(2)系统调用,映射这一段共享内存到自己的地址空间内,就可以使用
了。
一旦一段共享内存被创建,它就成为系统级的一个资源,即使所有使用它的进程退出了,
它仍然存在,除非显示的执行shmctl(2)或ipcrm(1)删除它。这非常类似一个文件。实际上文
件也是一种进程通讯方式。但和内核进程管理这部分没啥关系。
Linux的共享内存,确实是使用文件封装了。这是Linux(Unix)的哲学。一切皆文件。
所以我们通过pmap查看进程的地址空间,可以看到共享内存地址段,映射到一个名为
"SYSV"开头的文件上。该文件位于一个tmpfs文件文件系统上。不对外部暴露。相关代码定
义在"ipc/shm.c"。
shmget就是创建文件。shmat就是映射文件的到自己的地址空间,和mmap一个普通文件
是一样的。
你可以使用mount命令挂载一个tmpfs文件系统到一个目录,进程访问这个目录内的文件,
就是访问内存。如果多个进程同时mmap一个tmpfs文件系统上的文件到自己的地址空间,也
就是起到共享内存作用了。shmget只不过把我们这种手工创建的方式封装起来了,并把底层
的tmpfs屏蔽掉了而已。

 

 

 

 

 

 

posted @ 2014-07-11 15:39  holycrap  阅读(312)  评论(0编辑  收藏  举报