Linux进程通信:命名管道FIFO小结

2021-09-24 14:45

Linux进程通信:命名管道FIFO小结,有实例

Linux下进程之间通信可以用命名管道FIFO完成。命名管道是一种特殊类型的文件,因为Linux中所有事物都是文件,它在文件系统中以文件名的形式存在。

在程序中,我们可以使用两个不同的函数调用来建立管道:

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char *filename, mode_t mode);

int mknode(const char *filename, mode_t mode | S_IFIFO, (dev_t) 0 );

下面先来创建一个管道:

view plaincopy to clipboardprint?

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/stat.h>

int main()

{

int res = mkfifo("/tmp/my_fifo", 0777);

if (res == 0)

{

printf("FIFO created\n");

}

exit(EXIT_SUCCESS);

}

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/stat.h>

int main()

{

int res = mkfifo("/tmp/my_fifo", 0777);

if (res == 0)

{

Linux进程通信:命名管道FIFO小结,有实例

printf("FIFO created\n");

}

exit(EXIT_SUCCESS);

}

编译这个程序:

gcc –o fifo1.c fifo

运行这个程序:

$ ./fifo1

用ls命令查看所创建的管道

$ ls -lF /tmp/my_fifo

prwxr-xr-x 1 root root 0 05-08 20:10 /tmp/my_fifo|

注意:ls命令的输出结果中的第一个字符为p,表示这是一个管道。最后的|符号是由ls命令的-F选项添加的,它也表示是这是一个管道。

虽然,我们所设置的文件创建模式为“0777”,但它被用户掩码(umask)设置(022)给改变了,这与普通文件创建是一样的,所以文件的最终模式为755。

打开FIFO一个主要的限制是,程序不能是O_RDWR模式打开FIFO文件进行读写操作,这样做的后果未明确定义。这个限制是有道理的,因为我们使用FIFO只是为了单身传递数据,所以没有必要使用O_RDWR模式。如果一个管道以读/写方式打开FIFO,进程就会从这个管道读回它自己的输出。如果确实需要在程序之间双向传递数据,最好使用一对FIFO,一个方向使用一个。

当一个Linux进程被阻塞时,它并不消耗CPU资源,这种进程的同步方式对CPU而言是非常有效率的。

有关Linux下命名管道FIFO的读写规则可以参见之前所写的一篇文章:Linux命名管道FIFO的读写规则。

Linux进程通信:命名管道FIFO小结,有实例

一、实验:使用FIFO实现进程间通信

两个独立的程序:

1. 生产者程序,它在需要时创建管道,然后尽可能快地向管道中写入数据。

2. 消费者程序,它从FIFO中读取数据并丢弃它们。

生产者程序fifo2.c:

view plaincopy to clipboardprint?

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <fcntl.h>

#include <limits.h>

#include <sys/types.h>

#include <sys/stat.h>

#define FIFO_NAME "/tmp/Linux/my_fifo"

#define BUFFER_SIZE PIPE_BUF

#define TEN_MEG (1024 * 1024 * 10)

int main()

{

int pipe_fd;

int res;

int open_mode = O_WRONLY;

int bytes = 0;

char buffer[BUFFER_SIZE + 1];

if (access(FIFO_NAME, F_OK) == -1)

{

res = mkfifo(FIFO_NAME, 0777);

if (res != 0)

{

fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME);

exit(EXIT_FAILURE);

}

}

Linux进程通信:命名管道FIFO小结,有实例

printf("Process %d opening FIFO O_WRONLY\n", getpid());

pipe_fd = open(FIFO_NAME, open_mode);

printf("Process %d result %d\n", getpid(), pipe_fd);

if (pipe_fd != -1)

{

while (bytes < TEN_MEG)

{

res = write(pipe_fd, buffer, BUFFER_SIZE);

if (res == -1)

{

fprintf(stderr, "Write error on pipe\n");

exit(EXIT_FAILURE);

}

bytes += res;

}

close(pipe_fd);

}

else

{

exit(EXIT_FAILURE);

}

printf("Process %d finish\n", getpid());

exit(EXIT_SUCCESS);

}

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <fcntl.h>

#include <limits.h>

#include <sys/types.h>

#include <sys/stat.h>

#define FIFO_NAME "/tmp/Linux/my_fifo"

#define BUFFER_SIZE PIPE_BUF

#define TEN_MEG (1024 * 1024 * 10)

int main()

{

int pipe_fd;

int res;

int open_mode = O_WRONLY;

Linux进程通信:命名管道FIFO小结,有实例

int bytes = 0;

char buffer[BUFFER_SIZE + 1];

if (access(FIFO_NAME, F_OK) == -1)

{

res = mkfifo(FIFO_NAME, 0777);

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, open_mode);

Linux进程通信:命名管道FIFO小结.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:吉林省长春外国语学校2012届高三第一次月考(历史)

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: