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

IPC进程间通信:使用命名管道mkfifo一日心血来潮,想要复习进程间通信进程间通信的方法很多,如管道、共享内存等下面的程序在主线程执行时创建了一个名为listener的监听线程主线程从用户获取输入,监听线程监听主线程获取的输入,用红色字体打印到终端上主线程和监听线程之间,通过命名管道"fifo_file"

大家好,欢迎来到IT知识分享网。IPC进程间通信:使用命名管道mkfifo"

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

下面的程序在主线程执行时创建了一个名为 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

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

进程间通信

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

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

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/31728.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信