UNIX/Linux 是多任务的操作系统,通过多个进程分别处理不同事务来实现,如果多个进程要进行协同工作或者争用同一个资源时,互相之间的通讯就很有必要了
进程间通信,Inter process communication,简称 IPC,在 UNIX/Linux 下主要有以下几种方式:
这里分享一下我在学习进程通讯过程中的笔记和心得
FIFO 有时被称为命名管道
匿名管道 pipe 只能在两个相关的进程之间使用,而且这两个相关的进程还要有一个共同的创建它们的祖先进程,而通过 FIFO 不相关的进程也能交换数据
在 sys/stat.h 中有关于 mkfifo 的原型声明
/* Create a new FIFO named PATH, with permission bits MODE. */
extern int mkfifo (__const char *__path, __mode_t __mode)
__THROW __nonnull ((1));
下面通过一个例子,演示一下 FIFO 的使用方法
有A、B两个进程(非亲缘),实现如下功能:
要求:用fifo做
提示:要用2个fifo
fifoB.c
#include <unistd.h> //access,read,write,close 都在这里声明
#include <sys/stat.h> //mkfifo 在这里声明
#include <errno.h> //EEXIST 和 errno 在这里定义
#include <stdio.h>
#include <stdlib.h> //exit 在这里声明
#include <fcntl.h> //O_RDONLY 和 O_WRONLY 还有open在这里定义和声明
#define MAXSIZE 1000
//process B
int slen(char *s) //定义一个计算字符串长度的函数
{
int i=0;
for(;*s!='\0';s++)i++;
return i;
}
char * srev(char *s) //这个函数用来翻转字符串
{
int i=0,len=slen(s);
char tmpc='\0';
for(i=0;i<len/2;i++)
{
tmpc=s[i];
s[i]=s[len-1-i];
s[len-1-i]=tmpc;
}
return s;
}
int main()
{
char * rfifo="/tmp/abfifo";
char * wfifo="/tmp/bafifo";
char buffer[MAXSIZE],tmpc='\0';
int i=0,rfd=0,wfd=0,res=-1,len=0,rres=0; //在定义变量的同时进行初始化,是一个好习惯
// mkfifo abfifo
if(-1 == access(rfifo,F_OK)) //如果rfifo不存在,则创建
{
if(0 > (mkfifo(rfifo,0600)) && (EEXIST != errno)) //如果创建rfifo失败,并且出错不是文件已经存在,则提示并返回
{
printf("cannot create fifo file %s\n",rfifo);
exit(res);
}
}
// mkfifo bafifo
if(-1 == access(wfifo,F_OK)) //如果wfifo不存在,则创建
{
if(0 > (mkfifo(wfifo,0600)) && (EEXIST != errno)) //如果创建wfifo失败,并且出错不是文件已经存在,则提示并返回
{
printf("cannot create fifo file %s\n",wfifo);
exit(res);
}
}
if(-1 == (rfd = open(rfifo,O_RDONLY))) //打开rfifo
{
printf("cannot open file:%s\n",rfifo);
return res;
}
if(-1 == (wfd = open(wfifo,O_WRONLY))) //打开wfifo
{
printf("cannot open file:%s\n",wfifo);
return res;
}
for (i=0;1 == (rres=read(rfd,&tmpc,sizeof(char)));i++) //从rfifo中遍历所有内容,都临时存放到tmpc中(一次一个字节)
{
buffer[i]=tmpc; //将tmpc存放到buffer中
printf("%c",tmpc); //将tmpc进行打印
if ('\0' == tmpc) break; //如果遇到字符串结尾,就跳出
}
if(-1 == rres) //如果read的返回值为-1,就代表读错误
{
printf("read error on %s\n",rfifo);
return res;
}
printf("\n");
srev(buffer); //将buffer内容翻转
printf("%s\n",buffer); //将翻转后的buffer输出
len=slen(buffer); //求buffer的长度
if( -1 ==(write(wfd,&buffer[1],sizeof(char)*(len-2)))) //将首尾去除后中间的部分写到wfifo中
{
printf("write error on : %s\n",wfifo);
return res;
}
close(rfd);
close(wfd); //收尾的文件描述符关闭
res=0;
return res;
}
fifoA.c
#include <stdio.h>
#include <malloc.h>
#include <string.h> //strlen,strcpy,strcat
#include <fcntl.h> //open,O_WRONLY,O_RDONLY
#include <stdlib.h> //exit
#include <unistd.h> //write,access,read,close
//process A
int main(int argc,char *argv[])
{
char * rfifo="/tmp/bafifo";
char * wfifo="/tmp/abfifo";
char tmpc='\0', * buffer=NULL;
int len=0,rfd=0,wfd=0,res=-1,i=0,rres=0; //在定义变量的同时进行初始化,是一个好习惯
if(2 != argc) //如果参数个数不达标,就提示并返回
{
printf("argument unmber error: need a string\n");
return res;
}
len=strlen(argv[1]);
buffer=(char *)malloc(sizeof(char)*(len+1)); //分配动态内存
if (-1==(wfd=open(wfifo,O_WRONLY))) //打开wfifo
{
printf("open fifo file error:%s\n",wfifo);
exit(res);
}
strcpy(buffer,argv[1]); //将参数复制给buffer
strcat(buffer,""); //buffer构成字符串
if (-1==write(wfd,buffer,sizeof(char)*(len+1))) //将buffer内容写到wfifo中
{
printf("write error on : %s\n",wfifo);
exit(res);
}
if(-1 == access(rfifo,F_OK)) //检测rfifo是否已经存在
{
printf("cannot access fifo file %s\n",rfifo);
return res;
}
if(-1 == (rfd = open(rfifo,O_RDONLY))) //打开rfifo
{
printf("cannot open pipe file:%s\n",rfifo);
return res;
}
for (i=0;1 == (rres=read(rfd,&tmpc,sizeof(char)));i++) //从rfifo中遍历所有内容,并且逐个存到tmpc中
{
buffer[i]=tmpc; //将tmpc 存到 buffer中
printf("%c",tmpc); //将tmpc输出
if ('\0' == tmpc) break; //遇到字符串结束符就跳出
}
if(-1 == rres) //如果读的返回结果为-1就表明读错误
{
printf("read error on %s\n",rfifo);
return res;
}
printf("\n");
close(wfd);
close(rfd);
free(buffer); //进行收场的清理工作
res=0;
return res;
}
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。