您的位置:首页 > 运维架构 > Linux

linux进程通信机制之无名管道&有名管道

2015-05-21 13:04 537 查看
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">前几天看看了linux多线程,最近就想看看linux进程间是如何通信的。</span>
linux进程通信相比大家都是很熟悉了,在操作系统的教材上也早已列举出来这里咱们在回顾一下

linux进程通信方式:

1.管道------包括有名管道和无名管道

2.信号量机制

3.共享存储区

4.消息队列

下面给出各个方式的实现过程:

1.无名管道:

这个恐怕也是进程通信最简单的方式了,不过这个无名管道只能用于父子进程或者兄弟进程之间的通信,因此扩展性不好。

使用无名管道首先要定义一个int 数组作为文件描述符 int fad[2],fad[0]用户读,fad[1]用户写,创建管道的操作是pipe(fad),当成功是返回0.

还需要用到两个方法:

ssize_t read(int fd, void *buf, size_t count); //从管道中读count字节的数据到buff指向的内存中

ssize_t write(int fd, const void *buf, size_t count);//把buff指向的数据向管道中写count字节

实现代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
void main(){
    int fad[2];
    int pid;
    if((pipe(fad)<0)){
        printf("create pipe failed!\n");
        exit(0);
    }
    if((pid=fork())<0){
        printf("create fork failed\n");
    }
    if(pid==0){
        sleep(1);
        close(fad[1]);
        char buff[1024];
        while(1){
            if(read(fad[0],buff,1024)>0){
                printf("child receive: %s \n",buff);
            }
            if(strncmp(buff,"quit",4)==0)break;
        }
        close(fad[0]);
        exit(0);
    }
    if(pid>0){
        close(fad[0]);
        char str[1024];
        while(1){
            printf("father said: \n");
            scanf("%s",str);
            write(fad[1],str,1024);
            sleep(1);
            if(strncmp(str,"quit",4)==0)break;
        }
        close(fad[1]);
        exit(0);

    }
}


运行结果:



2.有名管道

有名管道相对于无名管道就有点麻烦了,但是它可以用于没有任何关系的进程之间的通信,因此可扩展行很好。有名

管道提供了一个路径名与之关联,让fifo的文件存在于系统中,只要知道文件路径,就可以进行访问,在这里看到fifo是否可以想到内存调度里的先进先出策略?没错,在这里也是指代先进先出。

有名管道的创建 :int mkfifo(const char *pathname, mode_t mode);成功时返回0,否则返回-1.

创建后需要打开管道:int open(const char *pathname, int flags, mode_t mode); 打开成功的话返回新的文件描述符,否则返回-1.

得到文件描述符后操作就和无名管道使用了。

实现代码:

write.c

<span style="font-size:18px;">#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>

#define myfifo "myfifo"
#define size 1024

void main(){
    char buff[size];
    int fd;
    int read_num;
    if(access(myfifo,F_OK)==-1){
        if((mkfifo(myfifo,0666))<0){
            printf("can not create fifo!\n");
            exit(0);
        }
    }
    if((fd=open(myfifo,O_WRONLY))==-1){
        printf("open fifo error!\n");
        exit(0);
    }
    while(1){
        printf("send>>");
        scanf("%s",buff);
        write(fd,buff,sizeof(buff));
        if(strncmp(buff,"quit",4)==0)break;
        sleep(1);
    }
}</span>


read.c

<span style="font-size:18px;">#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>

#define size 1024
#define myfifo "myfifo"
void main(){
    char buff[size];
    int fd;
    if(access(myfifo,F_OK)==-1){ 查看管道文件是否存在
        if(mkfifo(myfifo,0666)<0){//创建管道
            printf("create fifo failed!\n");
            exit(0);
        }
    }
    if((fd=open(myfifo,O_RDONLY))==-1){
        printf("can not open myfifo!\n");
        exit(0);
    }

    while(1){
        read(fd,buff,sizeof(buff));
        printf("receive: %s\n",buff);
        if(strncmp(buff,"quit",4)==0){
            break;
        }
        sleep(1);
    }
    close(fd);
    exit(0);
    
}</span>


执行结果:



新手测试,若高手们发现错误,麻烦及时批评指正,大家共同学习,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: