首页 > 系统相关 >IPC进程间通信:使用命名管道mkfifo

IPC进程间通信:使用命名管道mkfifo

时间:2023-02-09 00:22:57浏览次数:68  
标签:IPC mkfifo pthread fifo 间通信 file printf path open

一日心血来潮,想要复习进程间通信
进程间通信的方法很多,如管道、共享内存等

下面的程序在主线程执行时创建了一个名为 listener 的监听线程
主线程从用户获取输入,监听线程监听主线程获取的输入,用红色字体打印到终端上
主线程和监听线程之间,通过命名管道 "fifo_file" 通信

代码(已验证可执行)

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

void listen_handler();
int main(){
	char c;
	int ret;
	char str[BUFSIZ] = {0};
	int len;
const char* fifo_path="./fifo_file";
	int fd;
	pthread_t listener;
	if(-1 == mkfifo(fifo_path, 0777)){
		printf("client create fifo file:%s failed.\n", fifo_path);
		perror("mkfifo failed");
	}else{
		printf("client create fifo file:%s successed.\n", fifo_path);
		
	}
	fd = open(fifo_path, O_RDWR|O_NONBLOCK);
	if (0 != ret){
		printf("open fifo file failed.\n");
		return 0;
	}else{
		printf("open fifo file successed.\n");
	
	}
	ret = pthread_create(&listener, NULL, listen_handler, NULL);
	if (0 != ret){
		printf("create thread failed.\n");
		return 0;
	}
	ret = pthread_detach(listener);
	if (0 != ret){
		printf("detach thread failed.\n");
		return 0;
	}
	printf("client started.\n");
	printf("press q to quit.\n");
	while(1){
		//gets(str, BUFSIZ);
		len = getline(&str, &len, stdin);
		len = strlen(str);
		printf("client get line of length %d: %s\n", len, str);
		if('q' == str[0]){
			break;
		}	
		if(-1 == write(fd, str, len)){
			perror("write data error:");
		}
	
	}
	close(fd);
	return 0;

}
void listen_handler(){
	char msg[BUFSIZ] = {0};
	int fd;
	int ret;
const char* fifo_path="./fifo_file";
	printf("\033[41;1mserver is listening...\033[0m\n");
	if(-1 == mkfifo(fifo_path, 0777)){
		printf("listneer create fifo file:%s failed.\n", fifo_path);
	}else{
		printf("listener create fifo file:%s successed.\n", fifo_path);
	}	
	fd = open(fifo_path, O_RDONLY);
	if(-1 == fd){
		printf("open fifo %s failed.\n", fifo_path);
		return;
	}else{
		printf("open fifo file successed.\n");
	}
	
	while(1){
		if(-1 != read(fd, msg, BUFSIZ)){
			printf("\033[41;1mreceive data: %s\033[0m\n", msg);
		}else{
			perror("read data error:");
		}
	}
	printf("end of listener.\n");
}

主要参考:

命名管道 mkfifo

https://www.cnblogs.com/52php/p/5840229.html

进程间通信

https://www.cnblogs.com/CheeseZH/p/5264465.html

pthread

https://blog.csdn.net/weibo1230123/article/details/81410241

用到的函数

open
read
write
perror(调试用)
pthread_create
pthread_detach(不等待线程执行完毕)

注意点

若出现write data failed: Bad file descriptor

则是因为文件创建时候的权限和文件open时候的权限不一致
open时候的选项:
O_RDWR
O_RDONLY
O_WRONLY
O_NONBLOCK
mkfifo时候
0777
0666

若出现open后无反应,则需要查看open是否添加了非阻塞选项

O_NONBLOCK非阻塞

选项 O_NONBLOCK 表示非阻塞,加上这个选项后,表示open调用是非阻塞的,如果没有这个选项,则表示open调用是阻塞的。

open调用的阻塞是什么一回事呢?很简单,对于以只读方式(O_RDONLY)打开的FIFO文件,如果open调用是阻塞的(即第二个参数为O_RDONLY),除非有一个进程以写方式打开同一个FIFO,否则它不会返回;如果open调用是非阻塞的的(即第二个参数为O_RDONLY | O_NONBLOCK),则即使没有其他进程以写方式打开同一个FIFO文件,open调用将成功并立即返回。

对于以只写方式(O_WRONLY)打开的FIFO文件,如果open调用是阻塞的(即第二个参数为O_WRONLY),open调用将被阻塞,直到有一个进程以只读方式打开同一个FIFO文件为止;如果open调用是非阻塞的(即第二个参数为O_WRONLY | O_NONBLOCK),open总会立即返回,但如果没有其他进程以只读方式打开同一个FIFO文件,open调用将返回-1,并且FIFO也不会被打开。

pthread_detach vs pthread_join

pthread_join()即是子线程合入主线程,主线程阻塞等待子线程结束,然后回收子线程资源。
pthread_detach()即主线程与子线程分离,子线程结束后,资源自动回收。

pthread非系统默认库,需要编译时候链接
gcc main.c -lpthread

标签:IPC,mkfifo,pthread,fifo,间通信,file,printf,path,open
From: https://www.cnblogs.com/studentWangqy/p/17103830.html

相关文章

  • WinForm(十五)窗体间通信
    在很多WinForm的程序中,会有客户端之间相互通信的需求,或服务端与客户端通信的需求,这时就要用到TCP/IP的功能。在.NET中,主要是通过Socket来完成的,下面的例子是通过一个Tcp......
  • WinForm(十五)窗体间通信
    在很多WinForm的程序中,会有客户端之间相互通信的需求,或服务端与客户端通信的需求,这时就要用到TCP/IP的功能。在.NET中,主要是通过Socket来完成的,下面的例子是通过一个Tc......
  • WinForm(十五)窗体间通信
    在很多WinForm的程序中,会有客户端之间相互通信的需求,或服务端与客户端通信的需求,这时就要用到TCP/IP的功能。在.NET中,主要是通过Socket来完成的,下面的例子是通过一个Tc......
  • linux环境编程(3): 使用POSIX IPC完成进程间通信
    1.写在前面之前的文章总结了使用管道进行进程间通信的方法,除了pipe和fifo,Linux内核还为我们提供了其他更高级的IPC方式,包括共享内存,消息队列,信号量等,本篇文章会通过一个......
  • 进程间通信
    一、进程间通信(interprocesscommunication,简称IPC)指两个进程之间的通信。系统中每个进程都有自己的地址空间,并且相互独立、隔离,每个进程都处于自己的地址空间中。......
  • 进程间通信之fifo
    一、引言FIFO常被称为有名管道,不同于管道(pipe)。pipe仅适用于“有血缘关系”的IPC。但FIFO还可以应用于不相关的进程的IPC。实际上,FIFO是Linux基础文件类型中的一......
  • 进程间通信常见方式(4种,这里说管道、fifo、共享存储映射)
    学习地址IPC即进程间通信进程间通信框架如下:进程间通信方式如下:管道得有血缘关系管道前提作用于有血缘关系的进程间插曲mkfifof1实现原理内核借助环形......
  • linux环境编程(2): 使用pipe完成进程间通信
    1.写在前面linux系统内核为上层应用程序提供了多种进程间通信(IPC)的手段,适用于不同的场景,有些解决进程间数据传递的问题,另一些则解决进程间的同步问题。对于同样一种IPC......
  • 封装“啪”就画好了,很快啊-IPC向导设计SO16封装-PCB系列教程2-3
    目录​​手工创建SO芯片封装​​​​特殊粘贴快速放置焊盘​​​​使用IPC向导​​​​3D封装​​朋友们好啊,我是传统手工画封装的老工程师yummy老师.刚才有个朋友问我yummy......
  • 练习-使用IPC向导生成LQFP64封装-PCB系列教程2-3+
    系列教程的第3个案例会讲解STM32F405单片机的板子,这个单片机的封装是LQFP64。接下来以LQFP64做为案例,练习使用IPC向导。焊接练习板背面还有些空间,放几个芯片来练习下焊接。......