Linux系统编程.NO13——信号与管道

10.信号与管道

10.1.信号的概念

Linux系统中,信号是一个32位的整型,每个信号代表一种信息,都以 SIG开头,使用命令kill -l查看所有信号。前31位的信号是不可靠信号,后面的是可靠信号,不可靠是指不支持排队,可能造成信号丢失。常见信号有:
1)SIGHUP:使进程执行exit动作,用于退出终端时对终端下所有进程发出该信息以关闭进程,要么nohup忽略该信号,要么写成一个daemon守护进程。
2)SIGINT:终止进程,Ctrl+C发出的即是这个信号
3)SIGQUIT:终止进程,退出时会产生core文件
9)SIGKILL:强制终止进程,该信号不能被捕获、封锁或者忽略
15)SIGTERM:kill命令的默认信号,杀死一般正常进程
19)SIGSTOP:强制暂停进程,该信号不能被进程所处理
18)SIGCONT:对于被SIGSTOP暂停的进程使用,作用是恢复进程的运行,该信号一样无法被进程所处理,和SIGKILL一样
13)SIGPIPE:在网络编程中,如果客户端已经关闭了套接字,但是服务器调用了send函数,第一次会收到RST segment,如果再次调用send函数,服务器就会收到本信号,从而关闭该服务进程,一般会手动将该信号忽略。
17)SIGCHLD:当服务器采用fork函数生成子进程,子进程退出又需要使用wait函数回收资源,但如果不需要子进程退出后的状态,可以使用signal(SIGCHLD,SIG_IGN)让系统去回收子进程。

10.2.信号的响应

当进程接收到信号之后,可能产生三种动作,也就是三种响应方式:

  1. 忽略信号
  2. 执行系统默认动作
  3. 捕捉信号
    当然SIGKILL和SIGSTOP信号是不能被捕捉和忽略的,如果进程不做设置,则进程会进行默认处理。

10.3.信号控制函数

1.int kill(pid_t pid,int sig)
函数功能是发送一个信号,pid指接收信号的PID,sig是要发送的信号,返回0表示成功,返回-1表示失败。
pid>0表示发送给指定的进程
pid== 0表示将信号发给调用进程的同组进程,包括自己
pid==-1,指将信号发送给除祖宗进程以外的所有进程(前提是该进程有此权限)
pid<-1表示将信号给送给进程组为-pid的进程
头文件是<sys/types.h><signal.h>
2.int raise(int sig)
给当前进程发送信号,参数就是具体要发送的信号,成功返回0,失败返回非0值。
头文件是<signal.h>
3.unsigned int alarm(unsigned int seconds)
函数功能是设置一个定时器,返回值是上一个定时器的剩余时间,没有其他定时器则返回0,参数seconds是指定定时的时间,单位是秒。
每个进程都应该最多只有一个闹钟时间,如果使用alarm之前已经设置了其他闹钟并且还没有超时,则此次alarm就会返回上个闹钟所剩下的剩余值,并重新设置闹钟时间。
头文件是<unistd.h>
4.sighandler_t signal(int signum,sighandler_t handler)
作用是设置信号的响应方式,signum是指信号,handler是指响应方式(执行某个操作或者执行处理函数,而且该函数必须有一个参数,并且会默认将本信号作为参数传入该函数,而且调用该函数时只需要写函数名即可)
linux定义了三个宏,SIG_ERR用于作为signal函数出错的返回值,SIG_IGN作为signal函数第二个参数表示忽略这个信号,SIG_DFL也是可以作为signal函数第二个参数表示按照系统默认执行。
头文件<signal.h>
5.unsigned int sleep(unsigned int seconds)
睡眠函数,使当前进程睡眠,睡眠结束时返回0,否则返回剩余时间,参数seconds指定睡眠时长,单位是秒。
头文件是<unistd.h>
6.int pause(void)
暂停并等待信号,调用pause会使进程挂起,直到进程捕捉到一个信号,并且当执行完信号处理函数并返回时,pause才会返回。pause函数如果要和signal函数配合使用,signal必须要写在pause前面,返回值是-1.
头文件是<unistd.h>
7.void abort(void)
使进程异常停止,此函数使得内核向进程发送一个SIGABRT信号,进程可以捕捉该信号。
头文件是<stdlib.h>

10.4.管道概念

管道是一种进程间通信方式,通信双方通过管道进行数据交流,但是管道只能是半双工传输数据,任意时刻只能有一个数据流,即虽然双方可以互相发送数据,但是不能同时发数据。
使用管道的双方一定要有共同的祖先进程,管道通信是由一方将数据写入管道,然后另一方再从管道读取数据,这样就需要一个数据缓存区,该缓存区在内存中,所以读写速度很快,大小为4096字节(使用命令ulimit -p)可以查看缓存区大小(以512字节位单位),所以如果缓存已满,写函数就会阻塞,直到读函数读走数据再写入,如果没有读函数只有写函数,内核将发送SIGPIPE,系统将会退出程序。

10.5.创建管道函数

1.创建无名管道
int pipe(int fds[2])
功能是创建一个管道,成功返回0,失败返回-1.一个进程创建的管道会拥有两个管道描述符,fds[0]和fds[1],其中fds[0]是读取端,fds[1]是写入端。pipe要求通信双方必须是父子进程。
当两个进程通信时候,发送数据的一方关闭fds[0],使用fds[1],而接受数据的一方关闭fds[1],使用fds[0]. 失败返回-1,成功返回0.
头文件是<unistd.h>
2.创建有名管道
int mkfifo(const char *pathname,mode_t mode)
功能是创建一个有名管道,pathname是该管道文件路径名,mode是指定管道文件的访问权限,如直接填0664。
创建管道成功后,就可以使用open,read,write,close函数对文件进行读写等操作。失败返回-1,成功返回0.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值