管道打开,都要同时打开写端与读端,不然会在open函数产生阻塞!!!
无名管道
pipe•创建
- –int pipe (int fd[2])
- –返回0表示成功;fd[0]带回管道出口,fd[1]带回管道入口;
- –fd[0], fd[1]通过文件描述符来表示pipe的出口与入口,进程可以从fd[0]读,并向fd[1]写。
- – -1,出错
•销毁
- –close(fd[0]) 关闭读端
- –close(fd[1]) 关闭写端
pipe 进程间通信:
- •通过read/write实现pipe的读写。
- •read(fd[0]), 从出口读;write(fd[1]), 向入口写。
- •pipe主要用在亲缘进程间通信。
- •通常,先创建一个管道,再通过fork()创建子进程,子进程会复制管道。
Pipe操作注意事项:
- 只有在管道读端存在时才有意义.否则,向管道中写入数据的进程将收到内核传来的SIGPIPE信号,导致该进程终止.
- 当缓存没有数据时,读操作阻塞;当缓存满时,写操作阻塞.
- 管道保证不超过PIPE_BUF(一般为4096)个字节的写入操作是原子的,或者全部写入,或者一个都不写入.
fifo概念:
- 无命名管道是存在于内存中的,只能用于具有亲缘关系的进程之间.
- 有名管道可以使互不相关的两个进程实现彼此通信.
- 这种管道可以通过路径名来指定,在文件系统是可见的,管道建立后,两个进程就可以把它当作普通文件一样地读写.
- 命名管道是严格第按照先进先出规则的,所以又叫FIFO.
- 对管道和FIFO读总是从开始处返回,写总是把数据添加到末尾,不支持lseek操作
fifo 创建与销毁
- 通过命令创建 mknod fifoname p
- 通过接口创建 int mkfifo( const char * fifoname, mode_t mode)
- –创建完毕后,就可以对fifoname做I/O操作
- 通过命令销毁 rm fifoname
- 通过接口销毁 unlink(fifoname)
信号
信号是在软件层次上对中断机制的一模拟,是一种异步通信机制.
- 信号可以直接进行用户空间进程和内核进程之间的交互,内核进程可以利用它来通知用户空间进程发生了哪些系统事件.
- 信号可以在任何时候发给某一进程,而无需知道该进程的状态.
- 如果该进程当前并不处于执行状态,则该信号就由内核保存起来,直到该进程恢复执行时再传递给它.
- 如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程.
•信号来源
信号事件的发生有两个来源:
- 硬件来源(比如按下了键盘或者其它硬件故障),通常由内核进行通知
- 程序可以用kill,sigqueue,alarm, raise ,setitimer 来用触发信号
- Shell的kill命令也可用来发信号给指定的进程
•信号的用途及含义
- 前32种信号已经有了预定义值,每个信号有了确定的用途及含义,并且每种信号都有各自的缺省动作。如按键盘的CTRL ^C时,会产生SIGINT信号,对该信号的默认反应就是进程终止。
- 前32一般信号都分配特殊意义,用户自定义的消息,最好选择 SIGUSR1,SIGUSR2
- 前32个为不可靠信号,如果发现该信号已经在进程中注册,那么就忽略该信号(不重复排队).
- 后32个为可靠信号,不管该信号是否已经在进程中注册,都会被在注册一次(重复排队),因此信号就不会丢失