进程间通讯--有名管道

有名管道特点

1.对应管道文件,可用于任意进程间进行通讯
2.打开管道时可指定读写方式
3.通过文件IO操作,内容存放在内存中

有名管道创建–mkfifo

#include <unistd.h>
#include <fcntl.h>
int mkfifo(const char* path, mode_t mode);

1.成功时返回0,失败时返回EOF
2.path创建的管道文件路径,之后可对文件进行读写
3.mode管道文件的权限,如0666

代码示例

写程序

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
    int re; 
    int fd; 
    char buf[32];
    unlink("/myfifo");
    re = mkfifo("/myfifo", 0666);
    if (re == -1) 
    {   
        perror("mkfifo");
        return -1;                                                                                                                                      
    }   

    fd = open("/myfifo", O_WRONLY|O_CREAT|O_TRUNC);
    if (fd < 0)
    {   
        perror("open");
        return -1; 
    }   
    strcpy(buf, "fifo write test");
    
    while (1)
    {
        write(fd, buf, strlen(buf));
        sleep(1);
    }

    return 0;
} 

读程序

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>                                                                                                                                     
#include <fcntl.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
    int re; 
    int fd; 
    char buf[32];

    fd = open("/myfifo", O_RDONLY);
    if (fd < 0)
    {   
        perror("open");
        return -1; 
    }   

    while (1) 
    {   
        read(fd, buf, 32);
        printf("%d\n", strlen(buf));
        printf("%s\n", buf);
        memset(buf, 0, 32);
        sleep(1);
    }   
    
    return 0;
}
### 匿名管道原理 匿名管道是一种半双工的通信方式,数据只能在一个方向上流动,有固定的读端和写端。它是基于文件描述符的通信机制,通常用于具有亲缘关系的进程间通信,如父子进程。在创建匿名管道时,系统会在内核空间创建一个缓冲区,用于存储写入的数据。当一个进程向管道写入数据时,数据被放入缓冲区;另一个进程从管道读取数据时,数据从缓冲区中取出。数据被进程从管道读出后,在管道中该数据就不存在了。当进程去读取空管道的时候,进程会阻塞;当进程往满管道写入数据时,进程也会阻塞,管道容量通常为64KB [^1]。 ### 匿名管道使用方法 在C语言中,可以使用`pipe()`函数创建匿名管道,该函数的原型为`int pipe(int pipefd[2])`,其中`pipefd[0]`为读端,`pipefd[1]`为写端。以下是一个简单的示例代码: ```c #include<unistd.h> #include<sys/types.h> #include<errno.h> #include<stdio.h> #include<stdlib.h> int main() { int pipe_fd[2]; pid_t pid; char buf_r[100]; char* p_wbuf; int r_num; memset(buf_r,0,sizeof(buf_r)); if(pipe(pipe_fd)<0) /*创建管道*/ { printf("pipe create error\n"); return -1; } if((pid=fork())==0) /*创建子进程 子进程 OR 父进程?*/ { printf("\n"); close(pipe_fd[1]); sleep(2); /*为什么要睡眠*/ if((r_num=read(pipe_fd[0],buf_r,100))>0) { printf( "%d numbers read from the pipe is %s\n",r_num,buf_r); } close(pipe_fd[0]); exit(0); } else if(pid>0) { close(pipe_fd[0]); if(write(pipe_fd[1],"Hello",5)!=-1) printf("parent write1 Hello!\n"); if(write(pipe_fd[1],"Pipe",5)!=-1) printf("parent write2 Pipe!\n"); close(pipe_fd[1]); sleep(3); waitpid(pid,NULL,0); /*等待子进程结束*/ exit(0); } return 0; } ``` ### 有名管道原理 有名管道(FIFO)是一种特殊类型的文件,它在文件系统中以文件名的形式存在,因此可以用于不具有亲缘关系的进程间通信。有名管道同样是半双工的,数据只能在一个方向上流动。当一个进程打开有名管道进行写入时,另一个进程可以打开同一个有名管道进行读取,通过文件系统的机制实现进程间的数据传递。 ### 有名管道使用方法 在C语言中,可以使用`mkfifo()`函数创建有名管道,该函数的原型为`int mkfifo(const char *pathname, mode_t mode)`。以下是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #define FIFO_NAME "myfifo" int main() { int fd; char buffer[100]; // 创建有名管道 if (mkfifo(FIFO_NAME, 0666) == -1) { perror("mkfifo"); exit(1); } // 打开有名管道进行写入 fd = open(FIFO_NAME, O_WRONLY); if (fd == -1) { perror("open"); exit(1); } // 写入数据 strcpy(buffer, "Hello, named pipe!"); write(fd, buffer, strlen(buffer)); // 关闭有名管道 close(fd); return 0; } ``` 读取端代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #define FIFO_NAME "myfifo" int main() { int fd; char buffer[100]; // 打开有名管道进行读取 fd = open(FIFO_NAME, O_RDONLY); if (fd == -1) { perror("open"); exit(1); } // 读取数据 read(fd, buffer, sizeof(buffer)); printf("Read from named pipe: %s\n", buffer); // 关闭有名管道 close(fd); // 删除有名管道 unlink(FIFO_NAME); return 0; } ``` ### 匿名管道和有名管道的区别 - **通信范围**:匿名管道通常用于具有亲缘关系的进程间通信,如父子进程;而有名管道可以用于不具有亲缘关系的进程间通信,因为它通过文件系统中的文件名来标识。 - **创建方式**:匿名管道使用`pipe()`函数创建,只存在于内核空间;有名管道使用`mkfifo()`函数创建,在文件系统中以文件名的形式存在。 - **生命周期**:匿名管道的生命周期与创建它的进程相关,当进程结束时,匿名管道也会消失;有名管道的生命周期与文件系统相关,即使创建它的进程结束,有名管道仍然存在,直到被显式删除。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值