大家好,欢迎来到IT知识分享网。
一日心血来潮,想要复习进程间通信
进程间通信的方法很多,如管道、共享内存等
下面的程序在主线程执行时创建了一个名为 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