您的位置:首页 > 运维架构 > Linux

linux下c编程进程通信-管道与信号

2016-08-21 18:24 477 查看
进程管道通信与信号


在进程编程时一般会用到进程间的通信方式,管道与信号,管道分无名管道pipe与有名管道fifo,无名管道一般用于有亲缘关系之间的进程通信,如父子进程通信,fifo较多用于不同应用程序之间的进程通信通过建立管道文件,具体的通信机制,查看相应的书籍即可。

此部分程序前部分为无名管道通信,后部分为fifo的写入数据部分

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>

#define fifo_name "./my_fifo" //创建的管道路径,以文件的形式
/*
无名管道的创建:用pipe
输入输出重定向:pclose,popen
管道联系设备:dup,dup2,可以把一个设备的输出管道送到另一个设备的输入
具体使用方式查看相应的手册
有名管道fifo;
*/
int main(int argc,char *argv[])
{
pid_t pid;//用于无名管道测试
int fifo_pipe_fd;//用于有名管道fifo
int res;         //有名管道fifo成功写入字符个数
int pipedes[2];//0为读,1为写,无管道通信的文件指针入口的描述符
char string_test[]="fifo data test message char";
char dounastation[13];    //无名管道的接收方
char fifo_char[]="write data to read";
if(pipe(pipedes)==-1)//创建无名管道以数组为管道,一写一读
{
perror("pipe");
exit(EXIT_FAILURE);
}
if((pid=fork())==-1)//无名管道测试
{
perror("fork");
exit(EXIT_FAILURE);
}
else if(pid==0)
{
printf("write data from chirld-progress to father-progress\n");
if(write(pipedes[1],string_test,4096)==-1) //数组1写入数据到管道中
{
perror("write");
exit(EXIT_FAILURE);
}
else
{
printf("write data sucess\n");
printf("write to pipe data is: %s\n",string_test);
exit(EXIT_SUCCESS);
}
}
else if(pid>0)//创立成功在父进程中接受子进程通过无名管道发送来的数据,
{
//sleep(5);
wait(&pid);//等到子进程成功的把数据写入管道中结束进程后父进程中开始读取数据
printf("father-progress read data from pipe\n");
if((read(pipedes[0],dounastation,13))==-1)//读数据
{
perror("read");
exit(EXIT_FAILURE);
}
printf("read data from pipe is:%s\n",dounastation);

//开始有名管道测试fifo数据的写入
printf("fifo test\n");
if(access(fifo_name,F_OK)==-1)//管道文件是否存在
{
res = mkfifo(fifo_name,0777);//创建管道位于哪一个目录下可以修改
if(res!=0)
{
fprintf(stderr,"could not creat fifo%s\n",fifo_name);
exit(EXIT_FAILURE);
}
}
printf("process %d opening FIFO O_WRONLY\n",getpid());
fifo_pipe_fd=open(fifo_name,O_WRONLY);//打开管道设备文件
printf("the file descriptor is %d\n",fifo_pipe_fd);//管道文件的文件描述符是
if(fifo_pipe_fd!=-1)
{
res=write(fifo_pipe_fd,string_test,sizeof(string_test));
if(res==-1)
{
fprintf(stderr,"write pipe error\n");
exit(EXIT_FAILURE);
}
printf("write data and number is %s,%d\n",string_test,res);
(void)close(fifo_pipe_fd);//写入完毕关闭管道
}
else

exit(EXIT_FAILURE);
printf("process %d finish\n",getpid());
exit(EXIT_FAILURE);
}
return 0;
}


以下部分代码为fifo的读取数据部分代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#define fifo_name "./my_fifo"   //读取有名管道文件路径
int main(int argc ,char *argv[])
{
int fifo_pipe_fd; //有名管道文件描述符
int res;
char read_fifo[4096]; //数据读取缓冲空间
int byte_read_num;    //数据字节大小
memset(read_fifo,'\0',sizeof(read_fifo));//用于对已开辟的读取数据缓存空间进行请0
printf("process %d opening fifo O_RDONLY\n",getpid());//获取当前pid
fifo_pipe_fd = open(fifo_name,O_RDONLY);//打开管道获得文件描述符
if(fifo_pipe_fd!=-1)
{
byte_read_num=read(fifo_pipe_fd,read_fifo,30);//直接以读取文件的方式读取管道文件的数据
printf("fifo read data is  %s\n",read_fifo);
close(fifo_pipe_fd);//关闭管道但是创建的管道还会存在与无名管道不同除非使用执行外部命令的函数进行删除
}
else
exit(EXIT_FAILURE);
printf("process %d dinished,%d fifo_read_num\n",getpid(),byte_read_num);
exit(EXIT_SUCCESS);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: