linux IPC之管道
来源:互联网 发布:c语言if语句嵌套 编辑:程序博客网 时间:2024/04/28 13:16
1)管道(有名管道和无名管道)
2)信号signal
3)消息队列Message Queue:是消息的链接表
4)共享内存Shared Memory:最有效的进程间通信方式
5)信号量semaphore:主要作为进程之间以及同一进程的不同线程之间的同步和互斥
6)套接字socket:用于网络中不同机器之间的通信
无名管道
在Linux中,管道是一种使用非常频繁的通信机制。从本质上说,管道也是一种文件,但它又和一般的文件有所不同,管道可以克服使用文件进行通信的两个问题,具体表现为:
限制管道的大小。实际上,管道是一个固定大小的缓冲区。在Linux中,该缓冲区的大小为1页,即4K字节,使得它的大小不象文件那样不加检验地增长。使用单个固定缓冲区也会带来问题,比如在写管道时可能变满,当这种情况发生时,随后对管道的write()调用将默认地被阻塞,等待某些数据被读取,以便腾出足够的空间供write()调用写。
读取进程也可能工作得比写进程快。当所有当前进程数据已被读取时,管道变空。当这种情况发生时,一个随后的read()调用将默认地被阻塞,等待某些数据被写入,这解决了read()调用返回文件结束的问题。
注意:从管道读数据是一次性操作,数据一旦被读,它就从管道中被抛弃,释放空间以便写更多的数据
表头文件 #include <unistd.h>
函数定义int pipe(int filedes[2]);
函数说明pipe()会建立无名管道,并将文件描述符由参数filedes数组返回,filedes[0]用于读管道,filedes[1]用于写管道。只能用于有亲缘关系的进程之间通信。成功返回0,错误返回-1。
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>int main(int argc, char **argv){int fd[2];char buf[1024] = "every day is good day";int ret=0;if(pipe(fd) < 0) {//创建无名管道perror("piple");exit(1);}//fd[0]用于读管道, fd[1]用于写管道pid_t pid;if((pid = fork()) == 0) { //创建一子进程close(fd[0]);ret = write(fd[1], buf, strlen(buf));if (ret < 0) {perror("write");exit(1);}printf("write %d bytes [%s]\n", ret, buf);close(fd[1]);} else if(pid > 0) {close(fd[1]);ret = read(fd[0], buf, sizeof(buf));printf("%d bytes read from the pipe is [%s]\n", ret, buf);if (ret < 0) {perror("read");exit(1);}close(fd[0]);}return 0;}
有名管道
表头文件#include <sys/types.h>
#include <sys/stat.h>
函数定义
int mkfifo(const char *pathname, mode_t mode);
函数说明 mkfifo()会依参数pathname建立特殊的FIFO文件,该文件必须不存在,而参数mode为该文件的权限(mode&~umask)
mode specifies the FIFO's permissions. It is modified by the process's umask in the usual way: the permissions of the created file are (mode & ~umask)
umask值也会影响到FIFO文件的权限,mkfifo()建立的FIFO文件其他进程都可以用读写一般文件的方式存取。
当使用open()来打开FIFO文件时,O_NONBLOCK会有影响。当使用O_NONBLOCK时,打开FIFO文件读取的操作会立即返回,但是若还没有其他进程打开FIFO来读取,则写入的操作会返回ENXIO错误代码
当没有使用O_NONBLOCK文件,打开FIFO文件读取的操作会等到其他进程打开FIFO文件来写入才正常返回,同样,打开FIFO文件来写入的操作会等到其他进程打开FIFO文件来读取后才正常返回
#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#define FIFO "/tmp/myfifo" //有名管道文件名int main(int argc, char **argv){int fd;int ret = 0;umask(0);char buf[]="hello world";char buf1[1024];if (mkfifo(FIFO, 07777) < 0) {perror("mkfifo");}pid_t pid;if ((pid = fork()) == 0){fd = open(FIFO, O_WRONLY);ret = write(fd, buf, strlen(buf));printf("write %d bytes, [%s]\n", ret, buf);close(fd);} else if(pid > 0) {fd = open(FIFO, O_RDONLY);ret = read(fd, buf1, sizeof(buf1));printf("read %d bytes, [%s]\n", ret, buf);close(fd);}unlink(FIFO);return 0;}
- linux IPC之管道
- linux IPC 之管道
- Linux-IPC之管道
- 【Linux编程】IPC之管道
- Linux IPC 之管道通信
- linux ipc之匿名管道
- Linux IPC 2之管道
- Linux IPC通讯之-管道(PIPE、FIFO)
- Linux IPC之管道和FIFO
- linux ipc—管道
- linux IPC--管道
- [总结]IPC之管道
- IPC通信之管道
- IPC通信之管道
- IPC通信之-管道
- IPC之管道详解
- IPC之管道详解
- IPC之---管道
- IT人生路
- 汉诺塔
- 基类和派生类的成员访问
- 数据库三大范式的理解
- Linux top command illustration
- linux IPC之管道
- 第十三周上机任务-项目1-fibnacct序列
- 装箱拆箱详细分析
- 注册DLL 和OCX 控件的便捷方法
- usaco Arithmetic Progressions 暴力破解
- 堆栈之说
- 给你一个单词a,如果通过交换单词中字母的顺序可以得到另外的单词b,那么定义b是a的兄弟单词。现在给你一个字典,用户输入一个单词,让你根据字典找出这个单词有多少个兄弟单词。
- 如何在window下的linux虚拟机中上网
- C++与LInux的学习之路(一)