一.管道

管道是Linux支持的最初Unix IPC形式之一,具有以下特点:
A. 管道是半双工的,数据只能向一个方向流动;
B. 需要双工通信时,需要建立起两个管道;
C. 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);
D. 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。

匿名管道的创建:该函数创建的管道的两端处于一个进程中间,在实际应用中没有太大意义;因此,一个进程在由pipe()创建管道后,一般再fork一个子进程,然后通过管道实现父子进程间的通信。因此只要两个进程中存在亲缘关系(这里的亲缘关系指的是具有共同的祖先),都可以采用管道方式来进行通信。
 #include <unistd.h>
 int pipe(int fd[2]);

匿名管道的读写规则:数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。管道两端可分别用描述字fd[0]以及fd[1]来描述,需要注意的是,管道的两端是固定了任务的。即一端只能用于读,由描述字 fd[0]表示,称其为管道读端;另一端则只能用于写,由描述字fd[1]来表示,称其为管道写端。如果试图从管道写端读取数据,或者向管道读端写入数据 都将导致错误发生。一般文件的I/O函数都可以用于管道,如close、read、write等等。从管道中读取数据:如果管道的写端不存在,则认为已经读到了数据的末尾,读函数返回的读出字节数为0;当管道的写端存在时,
如果请求的字节数目大于PIPE_BUF, 则返回管道中现有数据字节数。下面例子给出了管道的具体应用,父进程通过管道发送一些命令给子进程,子进程解析命令,并根据命令作相应处理。

 1 #include <unistd.h>
 2 #include <sys/types.h>
 3 main()
 4 {
 5     int pipe_fd[2];
 6     pid_t pid;
 7     char r_buf[4];
 8     char** w_buf[256];
 9     int childexit=0;
10     int i;
11     int cmd;
12     
13     memset(r_buf,0,sizeof(r_buf));
14     if(pipe(pipe_fd)<0)
15     {
16         printf("pipe create error\n");
17         return -1;
18     }
19     if((pid=fork())==0)
20     //子进程:解析从管道中获取的命令,并作相应的处理
21     {
22         printf("\n");
23         close(pipe_fd[1]);
24         sleep(2);
25         
26         while(!childexit)
27         {    
28             read(pipe_fd[0],r_buf,4);
29             cmd=atoi(r_buf);
30             if(cmd==0)
31             {
32 printf("child: receive command from parent over\n now child process exit\n");
33                 childexit=1;
34             }
35             
36                else if(handle_cmd(cmd)!=0)
37                 return;
38             sleep(1);
39         }
40         close(pipe_fd[0]);
41         exit();
42     }
43     else if(pid>0)
44     //parent: send commands to child
45     {
46     close(pipe_fd[0]);
47     w_buf[0]="003";
48     w_buf[1]="005";
49     w_buf[2]="777";
50     w_buf[3]="000";
51     for(i=0;i<4;i++)
52         write(pipe_fd[1],w_buf[i],4);
53     close(pipe_fd[1]);
54     }    
55 }
56 //下面是子进程的命令处理函数(特定于应用):
57 int handle_cmd(int cmd)
58 {
59 if((cmd<0)||(cmd>256))
60 //suppose child only support 256 commands
61     {
62     printf("child: invalid command \n");
63     return -1;
64     }
65 printf("child: the cmd from parent is %d\n", cmd);
66 return 0;
67 }
View Code

相关文章:

  • 2021-11-18
  • 2022-12-23
猜你喜欢
  • 2021-12-11
  • 2021-06-07
  • 2021-12-11
  • 2021-12-21
相关资源
相似解决方案