免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1223 | 回复: 0
打印 上一主题 下一主题

Linux 系统编程 之 进程通讯 -> 管道 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-05 02:19 |只看该作者 |倒序浏览

                                                                /**********************************************************************************
*   说进程通讯之前先解释什么是进程?
*
*   ===================
*   ┏━━━━━━━┓  
*   ┃ A B C  ┃  
*   ┃ │ ┃ │  ┃  
*   ┃ │ ┃ │  ┃  
*   ┃ │ ┃ │  ┃  
*   ┃ │ ┃ │  ┃  
*   ┃ │ ▉ │  ┃  
*   ┃ │ ┃ │  ┃  
*   ┃ │ ┃ │  ┃  
*   ┃ ▉ ┃ │  ┃  
*   ┃ │ ┃ │  ┃  
*   ┃ │ ┃ │  ┃  
*   ┃ │ ┃ │  ┃  细竖线表示线程;  
*   ┃ │ ┃ ▉  ┃  粗竖线表示主进程;  
*   ┃ │ ┃ │  ┃  方块表示当前位置;  
*   ┃ │ ┃ │  ┃  方框表示进程封装;  
*   ┃ 1 2 3  ┃  字母表示进程名称;  
*   ┃ └─╂─┘  ┃  数字表示进程CPU地址。  
*   ┗━━━━━━━┛  
*      我就是进程  
*
*
*    1.进程如树根,线程如树干,所有线程都直接或间接由进程得来。  
*    2.B线程是程序运行时创建的,由他创建A和C,它就是树子的主树  
*     干,其它小树干(树枝)由它长出  
*    3.每个树枝(线程)几乎可以做到互不影响,砍断一个另两个仍然生长  
*    4.CPU如生长素,按顺序分别在ABC三个地方施加向上的一个推动线程  
*     的力,虽然CPU在某个时刻只在一个地点出现,但由于快速的切换导  
*     致我们无法发现,犹如快速切换具有相似性的一组静态图片可以使  
*     我们看到运动图像一样。  
*    5.当所有的树干都被砍断,树根的存在就不再有意义了,所以它会自  
*     动地“烂掉”。
*   from CSDN Google  :) 解释的不是很准确但是很生动  简单的说是OS分配运行空间的基本单位
*   注意 有MMU 和无MMU 都有进程这个概念 实现的方式是不同 但是必须要有用户代码参与实现
*   这里的指的的core 代码 可以几句汇编指令 也可以比较复杂 比如linux kernel
*   管道用于通讯的一种机制 上世纪60年代提出 一直用到今天
*   匿名管道 进程之间要有亲戚关系才可以使用 还会有一种叫 有名管道突破这个限制
*      
*/
大家先看这里 我对这片文章补充了下面内容
在linux 进程通讯方式简写为IPC 进程之间无法看见对方必须采用特殊方式管道是其中一种 本文介绍 匿名 和FIFO 2种
匿名管道必须是 亲缘关系的进程 半双工方式
看程序
/* gcc xx.c*/
/* 运行参数  ./a.out xxxxxxxxxxxxxxxxxx  */
  
#include
#include
#include
#include
#include
static struct{
        int pipe_fd[2];
        pid_t pid;
        char r_buf[1];
} data_pcb={0,};
#define init_pipe(object,member) \
        do{\
     if (pipe(object.member)) perror("pipe create error"); \
        }while(0)
#define Create_child(object,member) \
        do{\
                object.pid=fork();\
        }while(0)
extern int
main(int argc,char * argv[]){
     init_pipe(data_pcb,pipe_fd);
  
    if(argc Create_child(data_pcb,pid);
         if(!data_pcb.pid){
                close(data_pcb.pipe_fd[1]); //close write
                while(read(data_pcb.pipe_fd[0],&(data_pcb.r_buf),1)>0) //read is block!
                        write(1,&(data_pcb.r_buf),1);
                write(1,"\n",1);
                close(data_pcb.pipe_fd[0]);
                _exit(0);
        }
    if(data_pcb.pidwrite(data_pcb.pipe_fd[1],argv[1],strlen(argv[1])); //write is block!
           close(data_pcb.pipe_fd[1]);
           wait(NULL);
     puts("Game Over!\n");
         return 0;
}
//=============================================================================
但是我们能 突破这个限制 通过 dup 传递重定向 fd 看下面这个程序如何做到
#include
#include
#include
#include
int main()
{
        int data_processed;
        int file_pipes[2];
        const char some_data[] = "123";
        pid_t fork_result;
        if (pipe(file_pipes) == 0) {
                fork_result = fork();
                if (fork_result == (pid_t)-1) {
                        fprintf(stderr, "Fork failure");
                        exit(EXIT_FAILURE);
                }
                if (fork_result == (pid_t)0) {
                        close(0);                        int x=dup(file_pipes[0]);                        close(file_pipes[0]);                        close(file_pipes[1]);                        execlp("od", "od", "-c", (char *)0);
                        exit(EXIT_FAILURE);
                }
                else {
                        close(file_pipes[0]);
                        data_processed = write(file_pipes[1], some_data, \
                                        strlen(some_data));
                        close(file_pipes[1]);
                        printf("%d - wrote %d bytes\n", (int)getpid(), data_processed);
                }
        }
        exit(EXIT_SUCCESS);
}
gcc xxx.c
./a.out
RUN
@@@@@debian-NjingLt:~/C/Clib/process$ 0000000   1   2   3
0000003
//==============================================================================
命名管道  
我们先熟悉一个 命令 mknod  通过man mknod 参看用法  POSIX 还为我们提供一个mkfifo函数方便C编程
我们就在shell下学习 namepipe 如下
@debian-NanJing:~/C/Clib/process$ file xxxxxxxx: fifo (named pipe)@debian-NanJing:~/C/Clib/process$ ls -lh xxxxprw-r--r-- 1 vivi vivi 0  13:43 xxxx@debian-NanJing:~/C/Clib/process$ @debian-NanJing:~/C/Clib/process$ cat ^C@debian-NanJing:~/C/Clib/process$ cat [1] 11431@debian-NanJing:~/C/Clib/process$ echo "Namepipe? >xxxx Namepipe[1]+  Done                    cat @debian-NanJing:~/C/Clib/process$
我们通过命名管道把进程链接起来 按照通讯理论可以连接成星型 和菊花链 APUE2 上有图大家自己去看  重点看 man 7 pipe
PIPE_BUF
       POSIX.1-2001 says that write(2)s of less than PIPE_BUF bytes must be atomic: the output data  is  written  to  the
       pipe  as  a  contiguous sequence.  Writes of more than PIPE_BUF bytes may be non-atomic: the kernel may interleave
       the data with data written by other processes.  POSIX.1-2001 requires PIPE_BUF to be  at  least  512  bytes.   (On
       Linux,  PIPE_BUF  is  4096  bytes.)   The  precise semantics depend on whether the file descriptor is non-blocking
       (O_NONBLOCK), whether there are multiple writers to the pipe, and on n, the number of bytes to be written:
       O_NONBLOCK disabled, n  PIPE_BUF
              The write is non-atomic: the data given to write(2) may be interleaved with write(2)s by other process; the
              write(2) blocks until n bytes have been written.
       O_NONBLOCK enabled, n > PIPE_BUF
              If  the  pipe  is full, then write(2) fails, with errno set to EAGAIN.  Otherwise, from 1 to n bytes may be
              written (i.e., a "partial write" may occur; the caller should check the return value from write(2)  to  see
              how many bytes were actually written), and these bytes may be interleaved with writes by other processes.
PIPE_BUF 在头文件 #include  
下面 3个 demo 是 namepipe 的具体的操作 有兴趣可以下载调试下 3个demo 都写了简单的Makefile文件  SUN x4100  和 debian-lenny 测试过
make run 就可以演示  
重定向
demo1
demo2
demo3
               
               
               
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/94090/showart_2111629.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP