Linux下进程间通信(小结)上

之所以进程间需要通信,包括进行数据传输、资源共享、通知事件和进程控制等等。

现在Linux使用的进程间通信方式包括:

  • 管道和有名管道
  • 信号
  • 消息队列
  • 共享内存
  • 信号量
  • 套接字

一、管道

1、这里主要指无名管道,具有如下特点:

#、只能用于具有亲缘关系的进程之间通信。

#、是一个半双工通信模式,具有固定的读写端,先进先出。

#、可以看成是一种特殊的文件,可以使用普通的read()等函数,但是它不是普通文件,不属于任何文件系统,并且只存在于内核的内存空间中。

#、数据被读出后,将从管道中删除,其他读进程将不能再读到这些数据。

2、管道是基于文件描述符的通信方式,管道建立时,创建两个文件描述符fd[0]、fd[1],fd[0]固定用于读管道,fd[1]固定用于写管道。关闭管道只需要用close将两个文件描述符逐个关闭即可。创建管道可以调用pipe()来实现,语法要点如下:

实际应用中,通常是先创建一个管道,然后通过fork()创建一个子进程,它会继承父进程所创建的管道,就可以实现父子进程之间的读写操作。由于父子进程运行的次序不能保证,所以可以调用sleep()函数。另外,应该调用waitpid()函数来保证父子进程的同步。

二、有名管道(FIFO)

有名管道突破了无名管道的限制,可以在互不相关的进程间进行通信。它在文件系统中是可见的,可当成普通文件进行读写操作,严格遵循先进先出原则,不支持如lseek()等文件定位操作。有名管道可以用mkfifo()函数创建,语法要点如下:

打开FIFO时,非阻塞标志(O_NONBLOCK)将对以后的读写产生影响:

#、没有使用O_NONBLOCK:访问要求无法满足时进程阻塞,如试图读取空的FIFO,将导致进程阻塞。

#、使用O_NONBLOCK:访问要求无法满足时不阻塞,立刻出错返回,errno是ENXIO。

三、信号

信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式。信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。用户进程对信号的相应有三种方式,即忽略信号(注:SIGKILLSIGSTOP不能被忽略)、捕捉信号和执行缺省操作。

下面列举几种常见的信号:

@SIGHUP:从终端上发出的结束信号

@SIGINT:来自键盘的中断信号(ctrl+c

@SIGKILL:该信号结束接受信号的进程

@SIGTERMkill命令发出的信号

@SIGCHLD:标识子进程停止或结束的信号

@SIGSTOP:来自键盘(ctrl+Z)或调试程序的停止执行信号

@SIGALRM:当一个定时器到时的时候发出信号

1、信号的发送与捕捉

akill()raise()

它们不仅可以发送终止信号,也可以向进程发送其他信号,raise()只允许进程向自身发送信号。

函数语法要点如下:

balarm()pause()

alarm()可以在进程设置一个定时器,当指定时间到时,向进程发送SIGALARM信号,需要注意的是,一个进程只能有一个闹钟时间,如果调用alarm之前已为进程设置过闹钟时间,而且没有超时,则被新值所代换。

pasue()用于将调用进程挂起直到捕捉到信号为止,通常用于判断信号是否已到。

2、信号的处理

信号处理主要两种方式,一种使用简单的signal()函数,另一种是使用信号集函数组。主要介绍信号处理函数。

signal()只要指出处理的信号和处理函数即可,不支持信号传递信息,语法要点如下:

首先该函数原型指向一个无返回值并且带一个整形参数的函数指针,接着该原型带有两个参数,其中第二个参数可以是用户自定义的信号处理函数的函数指针。Linux还支持一个更新的信号处理函数sigaction()

 

 

你可能感兴趣的:(linux,linux,signal,kill,终端)