Linux-进程间通信之无名管道和有名管道demo

无名管道 Pipe

同主机进程间数据交互机制:

  • 无名管道(PIPE):只有创建该管道的程序,才能够找到该管道(亲缘进程通信)
  • 单向传输
  • 控制进程只有pipe的一端
  • pipe的阻塞操作
    *fd[0] 读 fd[1]写
    SIGPIPE
  • 无名管道的内核资源在通信两进程退出后会自动释放,不能像普通文件一样存储信息,不能使用lseek来修改当前pipe的使用位置

read write 返回-1
会收到sigpipe信号

Demo

#include<stdio.h>
#include<errno.h>
#include<sys/wait.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>

int main()
{
	
    int pipe_fd[2] = {-1,-1};
	
	
    if(pipe(pipe_fd) < 0){
        printf("pipe error, %s\n",strerror(errno));
        return 1;
    }

    pid_t id = fork();
	
    if(id == 0){
        //child write
        close(pipe_fd[0]);

        char *msg = "child write:enenshiwo\n";
        while(1){
            write(pipe_fd[1],msg,strlen(msg));
            sleep(1);
        }
		
		
    }else{
        //father read
        close(pipe_fd[1]);

        char buf[1024];
        while(1){
            buf[0] = '\0';
			 char *msg_f = "father write:enenshiwo\n";
            ssize_t _sz = read(pipe_fd[0],buf,sizeof(buf) - 1);
            if(_sz > 0){
                buf[_sz] = '\0';
            }

            printf("father read : %s\n",buf);
        }
        wait(NULL);
    }
    return 0;
}

有名管道 fifo

  • FIFO 是依赖于文件系统,

依赖于文件系统,像普通文件一样具有磁盘路径,文件权限和其他属性,所有程序都可以通过path找到有名管道

  • fifo是一个文件,存储信息在内存,当两个进程都消失,数据消息,文件只有接口的作用
  • mkfifo
    int mkfifo(const char* pathname, mode_t mode);
  • 单项通信
  • 只能够进行少量数据传输
  • 只能一对一进行传输
  • 两个进程,中途退出了一个进程,未退出的一端如果是写操作的话,返回sigpipe信号
  • 未退出的一端如果是阻塞读操作的话,该读操作不会继续阻塞,直接返回0

Demo

fifo_write.c

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

#define FIFO_NAME "/tmp/my_fifo"

int main(int argc,char *argv[])
{
    int pipe_fd;
    int res;
    char buffer[]="hello world!";

    if (access(FIFO_NAME, F_OK) == -1) 
	{
        res = mkfifo(FIFO_NAME, 0766);
        if (res != 0) 
		{
            fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME);
            exit(EXIT_FAILURE);
        }
    }

	printf("Process %d opening FIFO O_WRONLY\n", getpid());
    pipe_fd = open(FIFO_NAME, O_WRONLY);
    printf("the file's descriptor is %d\n", pipe_fd);

    if (pipe_fd != -1) 
	{
            res = write(pipe_fd, buffer, sizeof(buffer));
            if (res == -1) 
			{
                fprintf(stderr, "Write error on pipe\n");
                exit(EXIT_FAILURE);
            }
		printf("write data is %s,%d bytes is wirte\n",buffer,res);
        (void)close(pipe_fd); 
    }
    else 
        exit(EXIT_FAILURE);        
    printf("Process %d finished\n", getpid());
    exit(EXIT_SUCCESS);
}

fifo_read.c

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

#define FIFO_NAME "/tmp/my_fifo"

int main(int argc,char *argv[])
{
    int pipe_fd;
    int res;
    char buffer[4096];
    int bytes_read = 0;

    memset(buffer, '\0', sizeof(buffer));
    
    printf("Process %d opening FIFO O_RDONLY\n", getpid());
    pipe_fd = open(FIFO_NAME, O_RDONLY);
    printf("the file's descriptor is %d\n",pipe_fd);

    if (pipe_fd != -1) 
	{
            bytes_read = read(pipe_fd, buffer, sizeof(buffer));
			printf("the read data is %s\n",buffer);
        	close(pipe_fd);
    }
    else 
        exit(EXIT_FAILURE);
    printf("Process %d finished, %d bytes read\n", getpid(), bytes_read);
    exit(EXIT_SUCCESS);
}

猜你喜欢

转载自blog.csdn.net/weixin_45309916/article/details/107673082
今日推荐