欢迎使用CSDN-markdown编辑器
来源:互联网 发布:业务建模与数据挖掘 编辑:程序博客网 时间:2024/05/16 06:09
Linux进程通讯主要有管道与有名管道、消息、文件流、信号、共享内存和套接字等方式。
前段时间主要学习了管道与有名管道、共享内存和套接字。
这里主要记录管道与有名管道的学习过程。
管道:管道是单向、FIFO的字节流,它把一个进程的标准输出和另一个进程的标准输入连接在一起。写数据的进程从管道尾部写入数据,而读数据的进程则从管道头部读出数据,数据一旦读取,就会从管道中消失,其他进程无法再次读取该数据。管道提供堵塞机制,当进程在写数据进管道时,读数据的进程将会堵塞;当管道数据已经满时,写数据的进程将会堵塞。
清楚这些基本之后后,就主要是了解一些需要调用的函数。
(1)管道的创建:int pipe( int fd[2] )
返回值:当成功调用时,返回0,当调用失败时,返回-1。
其中fd[0]为读端口,fd[1]为写端口。
另外,还需要用到一些进程的函数
子进程的创建:pid_t fork( )
返回值:若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID,否则出错返回
这部分学习主要参考:http://blog.csdn.net/jason314/article/details/5640969
管道通讯是基于文件描述符工作的,因此需要使用read( )和write( )进行数据读写工作。
下面这段代码很清晰地表现出匿名管道的使用方式。
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<unistd.h>int main(){ pid_t pid; int fd[2]; int stat; char buf[5] = "abc\n"; if(pipe(fd)){ printf("pipe failed!\n"); exit(0); } pid=fork(); switch(pid){ case -1: printf("frok failed\n"); exit(0); case 0: close(fd[1]); read(fd[0],buf,5); printf("%s",buf); exit(0); default: close(fd[0]); write(fd[1],buf,5); wait(&stat); exit(0); } return 0;}
其中需要注意的是,pid=fork( ),当创建子进程时,子进程的pid=0,父进程的pid则为子进程的pid。当进入父进程时,进行写操作之后,调用wait( )函数。一旦调用,父进程便停止,等待直至子进程被销毁。
命名管道:由于匿名管道必须是在共同的祖先进程启动的进程间进行通讯,若要在没有任何关系的两个进程间进行通讯,可以采用命名管道的方式。而命名管道的机制与管道类似,但其间会多生成一个FIFO文件进行通讯。
(1)命名管道的创建:
int mkfifo(const char *filename, mode_t mode);int mknod(const char *filename, mode_t mode , dev_t dev);
其中,filename是fifo的文件名,mode指定fifo文件的权限。
若直接使用open( )对fifo文件进行读写操作,则可能会产生堵塞。
//send.c#include<stdio.h>#include<stdlib.h>#include<string.h>#include<fcntl.h>#include<sys/types.h>#include<sys/stat.h>int main(){ const char *filename = "fifo"; int fd; int n,i; char buf[10]; if(access(filename,F_OK)==-1) { n = mkfifo(filename,S_IFIFO|0666); if(n!=0) { printf("create fail!"); exit(0); } } if((fd = open(filename,O_WRONLY))==-1) { printf("open fail!"); exit(0); } while(1) { fgets(buf,10,stdin); write(fd,buf,strlen(buf)+1); memset(buf,'\0',10); } close(fd);}
在send.c中,先是创建fifo文件,然后直接打开fifo文件,并且对fifo文件进行写入操作。
//read.c#include<stdio.h>#include<stdlib.h>#include<string.h>#include<fcntl.h>#include<sys/types.h>#include<sys/stat.h>int main(){ const char *filename = "fifo"; int fd; int i; char buf[10]; if((fd = open(filename,O_RDONLY))==-1) { printf("open fail!"); exit(0); } while(1) { memset(buf,'\0',sizeof(buf)); read(fd,buf,10); printf("the words you get:%s",buf); } close(fd);}
与send.c对应,read.c中只需要打开fifo文件并读取至缓存中,然后显示出来。
其中加入access(filename,F_OK)是为了防止重复创建fifo文件报错。以上两个程序都是以堵塞的方式进行数据传输。要使用非堵塞方式,只需要在read.c更改一下
fd = open(filename,O_RDONLY|O_NONBLOCK))==-1
管道对本机多进程通讯发挥着很重要的作用,形式简单,使用便利,传输速率较快,当数据量较小时应当使用管道方式。
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 图像分割(Image Segmentation)
- Junit测试笔记
- linux之vim命令
- MAC使用secureCRT
- PHP数据类型转换(字符转数字,数字转字符)
- 欢迎使用CSDN-markdown编辑器
- 背景建模与前景检测1(Background Generation And Foreground Detection)
- checkbox 触发两次问题
- java中的观察者模式
- 新的知识点
- datatstage 中一直处于Ready 状态
- ios 制作最简单的日历 NSCalendar
- Python类、模块、包
- 背景建模与前景检测2(Background Generation And Foreground Detection Phase 2)