【linux】linux随记-系统编程-管道

进程间通信(ipc)

  • 数据传输
  • 资源共享
  • 时间通知
  • 进程控制

linux系统下的进程通信

  • 早起unix系统ipc

    • 管道:无名管道 、有名管道
    • 信号
    • fifo
  • system-v ipc

    • system-v 消息队列
    • system-v 信号量
    • system-v 共享内存
  • socket ipc

  • posix ipc

    • posix 消息队列
    • posix 信号量
    • posix 共享内存

无名管道

pipefd数组 pipefd[0] 是读描述符 pipefd[1]是写描述符
  • 无名管道只能局限于父子进程间的通信
  • 特点:
    • 特殊的文件(没有名字),无法用open,但能甩close
    • 只能通过子进程继承文件描述符来使用
    • write和read操可能会阻塞进程
    • 所有文件描述符被关闭后,无名管道被销毁

步骤

  • 父进程pipe无名管道
  • fork子进程
  • close无用端口
  • write/read读写端口
  • close读写端口
#include<stdio.h>
#include<sys/wait.h>
#include <unistd.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<fcntl.h>
#include <string.h>

int main()
{
    int pipefd[2];
    pid_t pid;
    int real_read,real_write;
    char buf[20];
    const char *data = "hello pipe\r\n";
    if(pipe(pipefd) < 0)
    {
        perror("pipe");
        exit(1);
    }
    if((pid = fork()) < 0)
    {
        perror("fork");
        exit(1);
    }
    else if(pid == 0)
    {
        close(pipefd[1]);
        if((real_read = read(pipefd[0],buf,sizeof(buf))) > 0)
        {
            printf("child:%d bytes read form pipe : %s\r\n",real_read,buf);
        }
        close(pipefd[0]);
        exit(0);
    }
    else
    {
        close(pipefd[0]);
        if((real_write = write(pipefd[1],data,strlen(data))) > 0)
        {
            printf("patern: %d bytes write to pipe : %s",real_write,data);
        }
        close(pipefd[1]);
        exit(0);
    }
    return 0;
}

有名管道

  • mkfifo()成功返回0 失败返回1

  • 特点

    • 有文件名,可以用open打开
    • 任意进程间数据传输
    • write和read可能会阻塞进程(read时,有数据则读出,无则等待;write时管道内若已被写满,则等待)
    • write具有原子性(有名管道,往管道内写数据时,先判断管道内的缓冲区是否能一次性存储要写入的数据,可以则写入数据,否则不写入数据,所以要么一次性全部写入数据,要么不写入数据,称之为原子性;无名管道,管道内还有空间,就继续写入,填满为止,故没有原子性)
  • 第一个进程mkfifo有名管道

  • open有名管道,write和read数据

  • close有名管道

  • 第二个进程open有名管道,write和read数据

  • close有名管道

    例子

    fifo_write.c
#include<stdio.h>
#include<sys/wait.h>
#include <unistd.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<fcntl.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#define MYFIFO "/home/wzt/Code/system_programming/part_7/namedpipe_read/myfifo"
#define MAX_BUFFER_SIZE 4096

int main(int argc, char **argv)
{
    int fd;
    char buf[MAX_BUFFER_SIZE];
    int real_write;
    if(argc <= 1)
    {
        printf("usage:./fifp_write string\r\n");
        exit(0);
    }
    else
    {
        char *pbuf = buf;
        memset(pbuf, 0, MAX_BUFFER_SIZE);

        for(int i=1;i<argc;i++)
        {
            int len = strlen(argv[i])+1;
            if( (MAX_BUFFER_SIZE-(pbuf - buf)) > len)
            {
                sprintf(pbuf,"%s ",argv[i]);
                pbuf +=len;
            }
            else 
                break;
        }
    }
    
     if(access(MYFIFO,F_OK) < 0)
    {
        if((mkfifo(MYFIFO, 0666)<0) && (errno != EEXIST))
        {
            printf("Cannot create fifo file\r\n");
            exit(1);
        }
    }
    fd = open(MYFIFO,O_WRONLY);
    if(fd < 0)
    {
        printf("open fifo file error\r\n");
        exit(1);
    }
    if((real_write = write(fd, buf, strlen(buf))) > 0)
    {
        printf("write : %s to fifo \r\n",buf);
    }
    close(fd);
    return 0;
}
fifo_read.c
#include<stdio.h>
#include<sys/wait.h>
#include <unistd.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<fcntl.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#define MYFIFO "/home/wzt/Code/system_programming/part_7/namedpipe_read/myfifo"
#define MAX_BUFFER_SIZE 4096//PIPE_BUF
int main(int argc, char **argv)
{
    char buf[MAX_BUFFER_SIZE];
    int fd;
    int real_read;
    if(access(MYFIFO,F_OK) < 0)
    {
        if((mkfifo(MYFIFO, 0666)<0) && (errno != EEXIST))
        {
            printf("Cannot create fifo file\r\n");
            exit(1);
        }
    }
    fd = open(MYFIFO,O_RDONLY);
    if(fd < 0)
    {
        printf("open fifo eerror\r\n");
        exit(1);
    }
    while(1)
    {
        memset(buf, 0, MAX_BUFFER_SIZE);
        if((real_read = read(fd,buf,MAX_BUFFER_SIZE)) > 0)
        {
            printf("read: %s from fifo\r\n",buf);
        }
    }
    close(fd);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值