linux c fifo阻塞写和非阻塞写,FIFO阻塞读写

本文介绍了Linux中FIFO(命名管道)用于进程间通信的原理,特别是阻塞和非阻塞模式的区别。通过示例代码展示了如何创建和使用FIFO,以及阻塞模式下读写进程的同步行为。读者将理解如何在FIFO读写过程中保持原子操作,确保数据传输的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pipe一般都要和fork结合起来用,所以多进程都是基于一个主进程产生的,有一定的关联性,假如两个毫无相关的进程要进行进程间通信,命名管道可以实现;一个进程向FIFO写数据,另一个进程从FIFO读取数据

为了保持原子操作,可以通过阻塞方式来打开FIFO,就算只有一个读进程或者只有一个写进程存在,也会阻塞住等待对应的另一个进程的出现

打开FIFO的方式有下面几种:

open(const char *path, O_RDONLY);

open(const char *path, O_WRONLY);

open(const char *path, O_RDONLY | O_NONBLOCK);

open(const char *path, O_WRONLY | O_NONBLOCK);

如果带上O_NONBLOCK,那么表示非阻塞,这样读和写只要成功打开FIFO就返回,而不管另一面的写和读到底存在与否,这样假如读进程先打开FIFO,不管写进程有没有从FIFO写入数据,读进程打开FIFO成功就返回了,说不定根本就没读取到数据;显然假如要保持同步,理论上进行数据传输,假如读进程先打开了FIFO,如果写进程还没有写入数据,需要阻塞住等待写进程写入数据从而停止阻塞从而读出数据,假如写进程线打开了FIFO,如果读进程还没来读,也可以阻塞起来等待读进程打开了FIFO

下面就是两个独立的读写进程,来进行数据传输:

首先是写进程write.c:

#include

#include

#include

#include

#include

#include

#define MAXSIZE 20

int main()

{

const int open_mode = O_WRONLY;

const char *fifo_file = "/home/lihui/this_fifo";

int fd;

char ch[MAXSIZE];

if (access(fifo_file, 0) == -1)

if (mkfifo(fifo_file, 0777) == -1){

printf("mkfifo failed!\n");

exit(1);

}

printf("Write pid: %d\n", getpid());

printf("Open mode: %d\n", open_mode);

printf("Input: ");

scanf("%s", ch);

fd = open(fifo_file, open_mode);

if (fd == -1){

printf("open fifo failed!\n");

exit(1);

}

if (write(fd, ch, strlen(ch)) == -1){

printf("write fifo failed!\n");

exit(1);

}

printf("Now write %d bytes!\n", strlen(ch));

close(fd);

return 0;

}

然后是读进程read.c

#include

#include

#include

#include

#include

#include

#define MAXSIZE 20

int main(){

int open_mode = O_RDONLY;

int fd;

char buffer[MAXSIZE];

const char *fifo_file = "/home/lihui/this_fifo";

if (access(fifo_file, 0) == -1){

printf("%s not found!\n", fifo_file);

exit(1);

}

printf("Read pid: %d\n", getpid());

printf("Open mode: %d\n", open_mode);

fd = open(fifo_file, open_mode);

if (fd == -1){

printf("open fifo failed!\n");

exit(1);

}

memset(buffer, 0, sizeof(buffer));

if (read(fd, buffer, MAXSIZE) == -1){

printf("read fifo failed!\n");

exit(1);

}

printf("Now read: %s, %d bytes\n", buffer, strlen(buffer));

return 0;

}

编译,执行,直接先执行读端,再来写

首先,读端会阻塞住:

[lihui@localhost ~]$ cc -o readfifo read.c

[lihui@localhost ~]$ cc -o writefifo write.c

[lihui@localhost ~]$ ./readfifo

Read pid: 1668

Open mode: 0

光标

然后,执行写端:

[lihui@localhost ~]$ ./writefifo

Write pid: 1677

Open mode: 1

Input: HelloWorld!

Now write 11 bytes!

再看读端:

[lihui@localhost ~]$ ./readfifo

Read pid: 1668

Open mode: 0

Now read: HelloWorld!, 11 bytes

这样可以看到进程间通信,以及阻塞情况

在写程序过程中,出了2次问题:

1:写端ch先定义的字符串指针,结果coredump了,换成字符串数组就好了

2:读端的buffer没有memset,结果会出现下面结果:

[lihui@localhost ~]$ ./a.out

Read pid: 1233

Open mode: 0

Now read: Helloworld!@, 12 bytes

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值