Linux系统编程进程间通信之无名管道及FIFO

声明:侵删

1. 无名管道

无名管道: pipe
无名管道特点:
只能用于具有血缘关系的进程之间通信
半双工,有具体的读端和写端
管道可以看成一个文件用read和write读写,但她不属于任何文件系统

管道创建函数
在这里插入图片描述管道创建出的两端处于一个进程中,一般是先用pipe创建管道,在fork创建子进程,子进程会继承父进程创建的管道
fd[0]固定用于管道的读端,fd[1]固定用于管道的写端。
管道只有读端存在时才有意义,没有读端会引起管道破裂,读端一直不读,缓冲区无法刷新,写端就一直堵塞。

在这里插入图片描述无名管道实例

//pipe.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <wait.h>
#define BUFFER_SIZE  256

int main()
{
    pid_t pid;
    int pipe_fd[2];
    int real_read,real_write;
    char buf[BUFFER_SIZE];
    char data[] = "pipe text";
    if (pipe(pipe_fd)<0)/*创建管道*/
    {
        perror("peipe");
        exit(1);
    }
    if((pid = fork()) < 0)
    {
        perror("fork is filed");
        exit(1);
    }
    if  (pid == 0)/*子进程*/
    {
        /*子进程关闭管道写描述符*/
        close(pipe_fd[1]);
        sleep(3);/*等待父进关闭不用文件描述符*/
        /*读取管道内容*/
        if((real_read = read(pipe_fd[0],buf,BUFFER_SIZE)) !=-1)
        {
            printf("%d bytes data from peipe is '%s'\n",real_read,buf);     
        }
        close(pipe_fd[0]);/*关闭管道读端*/
        exit(0);

    }
    if (pid > 0)/*父进程*/
    {
        close(pipe_fd[0]);/*关闭管道读端*/
        sleep(1);
        /*向管道中写数据*/
        if((real_write = write(pipe_fd[1],data,sizeof(data))) !=-1)
        {
            printf("%d bytes data write in pipe is '%s'\n",real_write,data);
        }
        close(pipe_fd[1]);/*关闭管道写端*/
        waitpid(pid,NULL,0);/*回收子进程*/
        exit(1);
    }

}

2. FIFO有名管道

fifo可以使两个互不相关的进程实现通信
fifo创建的管道是在文件系统中可见的,两个进程可以把管道当成文件去读写,管道遵循先进先出规则
fifo是可以堵塞的
读进程:
若该管道是阻塞打开, 且当前 FIFO 内没有数据, 则对读进程而言将一直阻塞直到有数据写入
若该管首是非阻塞打开,则不论 FIFO 内是否有数据,读进程都会立即执行读操作。
写进程:
若该管道是阻塞打开,则对写进程而言将一直阻塞到有读进程读出数据。
若该管道是非阻塞打开,则当前 FIFO 内没有读操作,写进程都会立即执行读操
mkfifo函数创建管道

关于创建的FIFO(所关联的那个文件),需要说明读写权限,书中给了一个默认权限:允许用户读写、组内成员和其他用户读,使用掩码的方式包括起来就是:S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH

在这里插入图片描述
fifo例程

/*read-fifo.c*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define FIFO_NAME  "/tmp/myfifo"
#define N 32
int main()
{
	char buf[N];
	int pfd;
     if(mkfifo(FIFO_NAME,0666 )< 0) /*创建读写管道*/
    {
        perror("mkfifo");
        exit(-1);
    }
	if((pfd=open(FIFO_NAME,O_RDONLY))<0)/*以只读方式打开管道   堵塞*/
	{
		perror("open");
		exit(-1);
	}
	printf("open myfifo!\n");
	while(read(pfd,buf,N)>0)
	{
		printf("%s   the lenth of string is %d \n ",buf,(int)strlen(buf));
        memset(buf,0,sizeof(buf));
	}
	close(pfd);

	return 0;
}

/*write_fifo.c*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define FIFO_NAME  "/tmp/myfifo"
#define N 32
int main()
{
	char buf[32];
	int pfd;

	if((pfd=(open(FIFO_NAME,O_WRONLY)))<0)
	{
		perror("open");
		exit(-1);

	}
	printf("open  myfifo !\n");
	while(1)
	{
		fgets(buf,N,stdin);
		if(strcmp(buf,"quit\n")==0)
		{
			break;
		}
		write(pfd,buf,strlen(buf));
	}
	close(pfd);



	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值