Chinaunix首页 | 论坛 | 博客
  • 博客访问: 17432
  • 博文数量: 12
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 130
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-04 10:14
文章分类
文章存档

2013年(12)

我的朋友

分类: C/C++

2013-12-15 21:04:59

进程之间的通信大致有:管道通信(有名管道和无名管道),信号,共享内存,信号量,消息队列,套接字。。。


##########无名管道###########
无名管道用于只能用于父子进程和兄弟进程之间进行通信


函数:int pipe(int fd[2])   头文件 #include 
fd[2]为文件描述符,fd[0]用于读,fd[1]用于写

例子:

#include
#include
#include
#include
#include

int main()
{
 int pipe_fd[2];
 int pid;
 int size;
 char buf[1024];
 
 if(pipe(pipe_fd)<0)//创建管道
 {
  fprintf(stderr,"error \n");
  exit(1); 
 }
 
 pid=fork();//创建进程
 if(pid==0)
 {//子进程读
  printf("this is child\n");
  close(pipe_fd[1]);//
  sleep(2);//睡眠等待父进程先写入
  if((size=read(pipe_fd[0],buf,1024))>0)
  {
   buf[size]='\0';
   printf("%d numbers read from pipe_fd[0]:%s\n",size,buf); 
  } 
  close(pipe_fd[0]);
  exit(0);
 } 
 if(pid>0)
 {//父进程写
  close(pipe_fd[0]);
  //printf("enter something to pipe_fd[1]:\n");
  //gets(buf);
  if(write(pipe_fd[1],"hello",5)!=-1);
    printf("write success\n");
  if(write(pipe_fd[1]," child",6)!=-1)
   printf("write child success\n");  
  close(pipe_fd[1]);
  sleep(3);//
  wait(NULL);//等待子进程运行结束
  exit(0);
 }
 
 return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
无名管道又被称为pipe,是进程间通信的一种方式。pipe具有以下特点:

●只能用于具有血缘关系的进程之间

●半双工的通信模式,具有固定的读端和写端

●一种特殊的文件,存在于内存中。可通过read、write对其操作

因为pipe存在于内存中,所以无法像操作普通文件那样通过指定路径来打开文件。通常的做法是在父进程中创建管道,再创建子进程。由于子进程继承了父进程打开的文件描述符,所以父子进程就可以通过创建的管道进行通信。

为了在父进程中创建管道,需要先定义一个包含两个元素的整型数组,用来存放管道读端和写端对应的文件描述符。该数组在创建管道时作为参数传递。要注意的是,管道是一种半双工方式,即对于进程来说,要么只能读管道,要么只能写管道。不允许对管道又读又写。

其中数组的第一个元素固定代表管道的读端,第二个元素代表管道的写端。对于一个进程来说,只会用到其中一个。

若读取管道时没有数据,则进程会被阻塞,直到有数据可读。写管道时除非管道已满,一般情况下写入操作很快会返回。
#######有名管道#############

有名管道:不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first
out
),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操作。
有名管道的创建

#include

#include

int mkfifo(const
char * pathname, mode_t mode)

该函数的第一个参数是一个普通的路径名,也就是创建后FIFO的名字。第二个参数与打开普通文件的open()函数中的mode 参数相同。如果mkfifo的第一个参数是一个已经存在的路径名时,会返回EEXIST错误,所以一般典型的调用代码首先会检查是否返回该错误,如果确实返回该错误,那么只要调用打开FIFO的函数就可以了。一般文件的I/O函数都可以用于FIFO,如closereadwrite等等
例子:
fifo_w.c写入

#include
#include
#include
#include
#include
#include
#include
#include

#define FIFO "/tmp/fifo.txt"

int main()
{
 int fd;
 char buf[1024];
 int size;
 
 fd=open(FIFO,O_WRONLY|O_NONBLOCK,0);
 
 printf("enter something:\n");
 gets(buf);
 write(fd,buf,strlen(buf));
 close(fd);
 
 return 0;
}

fifo_r.c读出

#include
#include
#include
#include
#include
#include
#include
#include

#define FIFO "/tmp/fifo.txt"

int main()
{
 int fd;
 int size;
 char buf[1024];
 
 if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
  printf("error creat\n");
 
 fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
 
 if(fd==-1)
  {printf("open error\n"),exit(1);}
 
 while(1)
 {
  if((size=read(fd,buf,1024))==-1)
  {
   if(errno==EAGAIN)
    printf("no data yet\n");
  }
  printf("read %s char :%s\n",buf);
  
  sleep(1);
 }
 
 pause();
 unlink(FIFO);
 
 return 0;
}

#include
#include
#include
#include
#include
#include
#include
#include

#define FIFO "/tmp/fifo.txt"

int main()
{
 int fd;
 int size;
 char buf[1024];
 
 if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
  printf("error creat\n");
 
 fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
 
 if(fd==-1)
  {printf("open error\n"),exit(1);}
 
 while(1)
 {
  if((size=read(fd,buf,1024))==-1)
  {
   if(errno==EAGAIN)
    printf("no data yet\n");
  }
  printf("read %s char :%s\n",buf);
  
  sleep(1);
 }
 
 pause();
 unlink(FIFO);
 
 return 0;
}

 

 

阅读(189) | 评论(0) | 转发(0) |
0

上一篇:初识linux下的多进程编程(1)

下一篇:没有了

给主人留下些什么吧!~~