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

linux之间进程通信

2016-03-24 23:44 447 查看
进程间通信方式:



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

int main(int argc,char *argv[])
{
int fd;

if(argc < 2)
{
fprintf(stderr,"usage : %s argv[1].\n",argv[0]);
exit(EXIT_FAILURE);
}

if(mkfifo(argv[1],0666) < 0 && errno != EEXIST)
{
fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));
exit(EXIT_FAILURE);
}

if((fd = open(argv[1],O_RDONLY)) < 0)
{
fprintf(stderr,"Fail to open %s : %s.\n",argv[1],strerror(errno));
exit(EXIT_FAILURE);
}

printf("open for read success.\n");

return 0;
}


View Code
[b]  1.4有名管道的读写规则


A.从FIFO中读取数据

  约定:如果一个进程为了从FIFO中读取数据而以阻塞的方式打开FIFO, 则称内核为该进程的读操作设置了阻塞标志

  <1>如果有进程为写而打开FIFO,且当前FIFO内没有数据,则对于设置了阻塞标志的读操作来说,将一直阻塞。对于没有设置阻塞标志读操作来说返回-1,当前errno值为EAGAIN,提醒以后再试。

  <2>对于设置阻塞标志的读操作说,造成阻塞的原因有两种:当前FIFO内有数据,但有其他进程正在读这些数据;另外就是FIFO内没有数据。解阻塞的原因则是FIFO中有新的数据写入,不论写入数据量的大小,也不论读操作请求多少数据量。

  <3>如果没有进程写打开FIFO,则设置了阻塞标志的读操作会阻塞

  <4>如果写端关闭,管道中有数据读取管道中的数据,如果管道中没有数据读端将不会继续阻塞,此时返回0。

  注意:如果FIFO中有数据,则设置了阻塞标志的读操作不会因为FIFO中的字节数小于请求读的字节数而阻塞,此时,读操作会返回FIFO中现有的数据量。

B.向FIFO中写入数据

  约定:如果一个进程为了向FIFO中写入数据而阻塞打开FIFO,那么称该进程内的写操作设置了阻塞标志。

  对于设置了阻塞标志的写操作:

  <1>当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。如果此时管道空闲缓冲区不足以容纳要写入的字节数,则进入睡眠,直到当缓冲区中能够容纳写入的字节数时,才开始进行一次性写操作。

  <2>当要写入的数据量大于PIPE_BUF时,Linux将不再保证写入的原子性。FIFO缓冲区一有空闲区域,写进程就会试图向管道写入数据,写操作在写完所有请求写的数据后返回。

对于没有设置阻塞标志的写操作:

  <1>当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。在写满所有FIFO空闲缓冲区后,写操作返回。

  <2>当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。如果当前FIFO空闲缓冲区能够容纳请求写入的字节数,写完后成功返回;如果当前FIFO空闲缓冲区不能够容纳请求写入的字节数,则返回EAGAIN错误,提醒以后再写。

注意:只有读端存在,写端才有意义。如果读端不在,写端向FIFO写数据,内核将向对应的进程发送SIGPIPE信号(默认终止进程)
write to fifo

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

#define MAX 655360

int main(int argc,char *argv[])
{
int n,fd,i;
char buf[MAX]="i am the buf in write";
//    string temp ;
if(argc < 2)
{
fprintf(stderr,"usage : %s argv[1].\n",argv[0]);
exit(EXIT_FAILURE);
}

if(mkfifo(argv[1],0666) < 0 && errno != EEXIST)
{
fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));
exit(EXIT_FAILURE);
}

if((fd = open(argv[1],O_WRONLY )) < 0)
{
fprintf(stderr,"Fail to open %s : %s.\n",argv[1],strerror(errno));
exit(EXIT_FAILURE);
}

printf("open for write success.\n");

while(1)
{
printf(">");
int i=0;
while((buf[i]=getchar())!='\n')
i++;
//       scanf("%s",&temp);
//      for(i=0;i<sizeof(temp);i++)
//              buf[i]=temp[i];
n = write(fd,buf,i);
printf("write %d bytes.\n",n);
}

exit(EXIT_SUCCESS);
}


read from fifo

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

#define MAX 20

int main(int argc,char *argv[])
{
int fd,n,i;
char buf[MAX];

if(argc < 2)
{
fprintf(stderr,"usage : %s argv[1].\n",argv[0]);
exit(EXIT_FAILURE);
}

if(mkfifo(argv[1],0666) < 0 && errno != EEXIST)
{
fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));
exit(EXIT_FAILURE);
}

if((fd = open(argv[1],O_RDONLY )) < 0)
{
fprintf(stderr,"Fail to open %s : %s.\n",argv[1],strerror(errno));
exit(EXIT_FAILURE);
}

printf("open for read success.\n");

while(1)
{
printf(">");
scanf("%d",&n);

n = read(fd,buf,n);

printf("Read %d bytes.\n",n);
for(i=0;i<20;i++)
printf("%c",buf[i]);
printf("\n");

}

exit(EXIT_SUCCESS);
}


将write to fifo 部分中,输入一个字符串进入到buf中,再将buf中这个字符串写入到 fifo中,另一个进程再从fifo中读出数据

可以将这两个程序运行,然后输入read和write FIFO大小就可以看到效果。

参考资料:
http://blog.csdn.net/w616589292/article/details/50957456 http://www.cnblogs.com/bastard/archive/2012/08/31/2664896.html#3311781
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: