进程之间通信之有名管道、无名管道(pipe),笔记


             进程之间的通信作用
1、数据传输   :一个进程需要将他的数据传到其他进程
2、资源共享
3、进程通知事件
4、进程控制 :有些进程完全控制另一个进程的执行,如调试状态啊
我们需要完全控制他的每一步操作;

通信发展历史
Linux进程间的通信IPC由以下几个部分发展而来:
1、UNIX进程之间的通信
2、基于system v进程间的通信
3、POSIX进程之间的通信(portable operating system interface)

现在Linux使用的进程间的通信方式包括;
1、管道和有名管道
2、信号
3、消息队列
4、共享内存
5、信号量
6、套接字

分类:无名管道和有名管道:前者用于父进程和子进程间的通信,后者可用于运行于同一系统
int  pipe(int filedis[2])函数创建:
当一个管道建立时,他会创建两个文件描述符:
filedis[0]用于读管道,filedis[1]用于写管道。

管道的读写
管道用于不同进程间的通信。通常先创建一个管道,在通过fork函数
创建一个子进程,该子进程会继承父进程所创建的管道。

调用fork()之前要先调用pipe(),否则子进程将不会继承文件描述符。

/******************无名管道的实现*******************************/

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main()
    {
         int pipe_fd[2];
         pid_t pid;
         char buf_r[100];
         char* p_wbuf;
         int r_num;
 
         memset(buf_r,0,sizeof(buf_r));
 
     /*创建管道           fork之前先pipl*/
             if(pipe(pipe_fd)<0)
                 {
                      printf("pipe create error\n");
                      return -1;
                  }
 
             /*创建子进程*/
         if((pid=fork())==0)  //子进程 OR 父进程?
             {
                  printf("\n");
                  close(pipe_fd[1]);
                  sleep(2); /*为什么要睡眠*/
  if((r_num=read(pipe_fd[0],buf_r,100))>0)
      {
           printf(   "%d numbers read from the pipe is %s\n",r_num,buf_r);
      } 
close(pipe_fd[0]);
exit(0);
   }

else if(pid>0)
{
  close(pipe_fd[0]);
  if(write(pipe_fd[1],"Hefrfro",5)!=-1)
   printf("parent write1 Hello!\n");
  if(write(pipe_fd[1],"                         程度vvfvf",5)!=-1)
   printf("parent write2                         常润茶ge!\n");
  close(pipe_fd[1]);
  sleep(3);
  waitpid(pid,NULL,0);                     /*等待子进程结束*/
  exit(0);
}
 return 0;
}

命名(FIFO)
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char *pathname,mode_t mod)
pathname:FIFO 文件名
mode :属性一旦创建FIFO,就可以用open打开他,另外close read write都可以

当打开FIFO时,非阻塞(O_NONBLOCK)
将对以后的读写产生如下影响
1、没有使用O_NONBLOCK:当访问进程无法满足时,进程将阻塞,否则就立即报错。

/******************有名管道读操作***************************/

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO "/tmp/myfifo"

main(int argc,char** argv)
{
 char buf_r[100];
 int  fd;
 int  nread;
 
 /* 创建管道 */
 if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST)) //FIFO 管道路径
              printf("cannot create fifoserver\n");
 
             printf("Preparing for reading bytes...\n");
 
             memset(buf_r,0,sizeof(buf_r));            // 为buf_r分配内存
 
     /* 打开管道 */
 fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);  //如果打开的没有数据,就反回空

if(fd==-1)
             {
                  perror("open");
                  exit(1); 
                 }
 while(1)
 {
  memset(buf_r,0,sizeof(buf_r));
  
  if((nread=read(fd,buf_r,100))==-1)  如果管道数据没有数据了,就打印no data yet
      {
           if(errno==EAGAIN)
            printf("no data yet\n");
      }
  printf("read %s from FIFO\n",buf_r);
  sleep(1);
 } 
 pause(); /*暂停,等待信号*/
 unlink(FIFO); //删除文件
}

/**************有名管道写操作*************************/

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO_SERVER "/tmp/myfifo"            //注意这里两个管道都是同一地址。

main(int argc,char** argv)           //if you dont understand this looking before articles
    {
         int fd;
         char w_buf[100];  // define the cpcity of shu zu
         int nwrite;
  
 /*打开管道*/
 fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
 
 if(argc==1)
     {
          printf("Please send something\n");
          exit(-1);
     }
 
 strcpy(w_buf,argv[1]);   // 把输入的参数放入到buf里面;
 
 /* 向管道写入数据 */

//nwrite=write(fd,w_buf,100))  ;  可加可不加!me not using!


if((nwrite=write(fd,w_buf,100))==-1)  //在这里把这个函数综合写了,如果不习惯可以独立一行创建
         {
          if(errno==EAGAIN)
           printf("The FIFO has not been read yet.Please try later\n");
         }
 else
  printf("write %s to the FIFO\n",w_buf);
}

end!

时间: 2024-10-14 06:48:20

进程之间通信之有名管道、无名管道(pipe),笔记的相关文章

IPC进程之间通信的几种方式

概念 进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是 共享内存区 .但是,系统空间却是“公共场所”,所以内核显然可以提供这样的条件. 除此以外,那就是双方都可以访问的 外设 了.在这个意义上,两个进程当然也可以通过磁盘上的普通文件交换信息,或者通过“注册表”或其它数据库中的某些表项和记录交换信息.广义上这也是进程间通信的手段,但是一般都不把这算作“进程间通信”.因为那些通信手段的效率

进程与进程之间通信Manager

1 #!/usr/bin/env python 2 from multiprocessing import Process,Manager 3 4 #Manager进程与进程之间通信 5 def Foo(i,dic): 6 dic[i] = 100+i 7 print(dic.values()) 8 if __name__ == '__main__': 9 manage = Manager() 10 dic = manage.dict() 11 for i in range(2): 12 p =

使用命名管道进程之间通信(转)

原文地址:http://www.cnblogs.com/yukaizhao/archive/2011/08/04/system-io-pipes.html 命名管道: 命名管道的功能比匿名管道更强大,可以在进程之间做双工通信(即通信的两个进程都是既可以读也可写的):命名管道也可以实现跨网络在不同机器之间进行通信.可以在多线程中创建多个NamedPipeServerStream实例,为多个client端服务.另外命名管道还支持消息传输,这样client端可以读取任意长度的消息,而无须知道消息的长度

linux程序设计——pipe调用在两进程之间通信(第十三章)

13.4    pipe调用 在看过高级的popen函数之后,再来看看底层的pipe函数.通过这个函数在两个程序之间传递数据不需要启动一个shell来解释请求的命令.它同时提供了对读写数据的更多控制. pipe函数的原型如下所示: #include <unistd.h> int pipe(int file_descriptor[2]); 参数:是一个由两个整数类型的文件描述符组成的数组. 返回值:该函数在数组中填上两个新的文件描述符,如果成功则返回0,如果失败则返回-1并设置errno来表明失

进程之间通信

IPC 指的是进程间通讯 之所以开启子进程 ,肯定需要他帮我们完成任务,很多情况下,需要将数据返回给父进程. 然而进程内存是物理隔离的 解决方案: 1.将共享数据放在文件中,就是慢 2.管道 subprocess 中那个管道只能单向通讯,必须有父子关系 3.共享一块内存区域 得操作系统帮你分配,速度快 第三钟实现Manager from multiprocessing import Process,Manager import time def task(dic): print("子进程&quo

信号量实现进程之间通信

一.信号量 信号量是一种数据操作锁,本身不具有数据交换功能,而是通过控制其他的通信资源来实现进程之间的通信,简单来讲,信号量相当于一个计数器,计数当前某种资源的个数.信号量的周期也是随内核的.为了解决多个程序同时访问一个共享资源引发的问题. 临界资源:多个进程能访问到的公共资源. 临界区:将能访问带临界资源的代码成为临界区. 同步:对临界资源的访问具有顺序性. pv 操作 p(sv)  sv>0 减1  sv=0   挂起的该进程执行 s(sv)  没有进程因等待sv而挂起就加1,有进程等待sv

跨进程(同一app不同进程之间通信)——Android自动化测试学习历程

视频地址:http://study.163.com/course/courseLearn.htm?courseId=712011#/learn/video?lessonId=877122&courseId=712011 一.问题: 1.如何做到一个app不同进程通信? 2.多个app通信(不同app) 3.注入事件运行脚本和调用隐藏api 二.一个app不同进程通信: 知识点: 1.Intent.binder 2.Service.Activity 3.Handler.view 4.Messeng

进程之间的信号通信,类型、处理机制笔记

          信号通信产生情况:1.当用户按某些按键时,产生信号2.硬件异常产生信号,无效存储.3.进程用kill函数将进程杀掉4.用户可以使用kill命令将信号发给其他进程 第一.信号类型SIGHUP  SIGTRAP SIGIOT SIGBUS SIGFPTSIGINT  SIGKILL SIGUSER1 SIGSEGV SIGUSER2SIGQUIT SIGPIPE SIGALRM SIGTERMSIGILL  SIGCHLD SIGCONT SIGSTOP SIGIO  SIGPW

进程通信-无名管道

无名管道:主要是针对进程通信的(自己感觉它有很大的局限性) 特点:它不是一个文件系统,不能按名访问,这也是它和有名管道之间最大的区别.无名管道只是一个系统内存里面的东西. 半双工模式,数据只能流向一个方向(老师给我们举得例子就是水厂的水到居民用水,不可能倒着流对吧). 进程之间通信,但是只能是有亲缘关系的进程才能进行通信?比如父子进程:因为在父子进程中,子进程拷贝父进程的数据段,这让这两个进程在通信的时候就有了相连的关系. 下面我们来看一下:无名管道的创建,写入,读取,关闭(我用的的是Liunx