Unix IPC之pipe

pipe创建函数:

#include <unistd.h>

/* Create a one-way communication channel (pipe).
   If successful, two file descriptors are stored in PIPEDES;
   bytes written on PIPEDES[1] can be read from PIPEDES[0].
   Returns 0 if successful, -1 if not.  */
int pipe (int __pipedes[2]);

下面是一个测试实例,有些未说明函数,如Pipe,是pipe的一个包裹函数,二者参数及用法一致,仅仅是在包裹函数中添加了出错信息。

void client(int, int);
void server(int, int);

int
main(int argc, char **argv)
{
    int     pipe1[2], pipe2[2];
    pid_t   childpid;

    Pipe(pipe1);    /* create two pipes */
    Pipe(pipe2);

    if ( (childpid = Fork()) == 0)          /* child */
    {
        Close(pipe1[1]);
        Close(pipe2[0]);

        server(pipe1[0], pipe2[1]); // 子线程作为服务器端
        exit(0);
    }
    /* 4parent */
    Close(pipe1[0]);
    Close(pipe2[1]);

    client(pipe2[0], pipe1[1]);

    Waitpid(childpid, NULL, 0);     /* wait for child to terminate */
    exit(0);
}
/**
 * 从客户端读取文件名,打开文件并将文件内容返回给客户端
 * @param readfd  管道读描述符
 * @param writefd 管道写描述符
 */
void server(int readfd, int writefd)
{
    int     fd;
    ssize_t n;
    char    buff[MAXLINE + 1];

    /* 4read pathname from IPC channel */
    if ( (n = Read(readfd, buff, MAXLINE)) == 0)
        err_quit("end-of-file while reading pathname");

    buff[n] = ‘\0‘;     /* null terminate pathname */

    if ( (fd = open(buff, O_RDONLY)) < 0)
    {
        /* 4error: must tell client */
        // 打开失败则直接将错误信息写入管道
        snprintf(buff + n, sizeof(buff) - n, ": can‘t open, %s\n", strerror(errno));
        n = strlen(buff);
        Write(writefd, buff, n);

    }
    else
    {
        /* 4open succeeded: copy file to IPC channel */
        while ( (n = Read(fd, buff, MAXLINE)) > 0)
            Write(writefd, buff, n);
        Close(fd);
    }
}

/**
 * 将键盘输入数据发送给服务器,并将服务器的回复信息显示在屏幕
 * @param readfd  管道读描述符
 * @param writefd 管道写描述符
 */
void client(int readfd, int writefd)
{
    size_t  len;
    ssize_t n;
    char    buff[MAXLINE];

    /* 4read pathname */
    Fgets(buff, MAXLINE, stdin); // 从键盘获取输入信息
    len = strlen(buff);     /* fgets() guarantees null byte at end */
    if (buff[len - 1] == ‘\n‘)
        len--;              /* delete newline from fgets() */

    /* 4write pathname to IPC channel */
    Write(writefd, buff, len); // 写入管道

    /* 4read from IPC, write to standard output */
    while ( (n = Read(readfd, buff, MAXLINE)) > 0)
        Write(STDOUT_FILENO, buff, n);
}

以上测试实例实现了一个如下的客户-服务器:

时间: 2024-10-10 22:44:02

Unix IPC之pipe的相关文章

01 UNIX IPC 第一弹 综述

UNIX IPC 第一弹 综述 0. 为什么会有这边文章? 一直对这方面的技术只有些模棱两可的了解,但又没有个统一完整的认识,在学习了<Modern Operating System>和<Advanced Programming in the UNIX Environmet>的相关章节后,做一个总结. 1. 什么是进程(process)?为什么要有进程? 进程是可执行程序加载到内存后,在CPU上执行的代码,包括一些相关的资源及状态,是一个动态的,变化的状态. 进程是系统资源分配的基

Unix IPC之Posix消息队列(1)

部分参考:http://www.cnblogs.com/Anker/archive/2013/01/04/2843832.html IPC对象的持续性:http://book.51cto.com/art/201006/207275.htm 消息队列可以认为是一个消息链表,某个进程往一个消息队列中写入消息之前,不需要另外某个进程在该队列上等待消息的达到,这一点与管道和FIFO相反.Posix消息队列与System V消息队列的区别如下: 1. 对Posix消息队列的读总是返回最高优先级的最早消息,

UNIX IPC: POSIX 消息队列 与 信号

POSIX消息队列可以注册空队列有消息到达时所触发的信号,而信号触发对应的信号处理函数. 下面是一份基本的消息队列和信号处理结合的代码(修改自UNIX网络编程:进程间通信) #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <mqueue.h> #include

UNIX IPC: POSIX 消息队列

首先在我的MAC OSX上试了一下虽然有_POSIX_MESSAGE_PASSING的宏定义,但是用gcc编译会提示没有mqueue.h头文件,先放一边.在Ubuntu上使用正常,不过POSIX消息队列通过ipcs命令是看不到的,需要通过如下方式进行查看: mount -t mqueue none /mnt ls -al /mnt ls列出的文件即为程序中创建的POSIX消息队列,消息队列的名称需要以“/”开头否则会提示参数非法.通过cat查看这个文件可以知道这个队列的一些参数如: [email

c/c++ unix ipc

一个例子 //c_unix.c #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #define UNIX_DOMAIN "/tmp/UNIX.domain" int main(void) { int connect_fd; int ret; char snd_buf[1024]; int i; static stru

IPC之PIPE

管道是一种只允许用在有亲属关系的进程间通信的方式,由函数pipe创建一个管道,read,write进行读写操作. #include <unistd.h> int pipe(int pipefd[2]); 参数pipefd[2]数组返回打开的读写描述符,pipefd[0]为读,pipefd[1]为写. 第一个问题:文件描述符怎么会出现一个只能读,一个只能写呢?猜想是对一个文件打开了2次,一个以只读打开,一个以只写打开.使用fcntl来验证下: #include <unistd.h>

multiprocessing在python中的高级应用-IPC 之 Pipe

作为使用队列的另一种形式,还可以使用管道在进程回见执行消息传递. Pipe( [ duplex]) 在进程之间创建一条管道,并返回元组(conn1,conn2),其中conn1和conn2是表示管道两端的Connection对象.默认情况下,管道是双向的.如果将duplex置为False,conn1只能用于接收,而conn2只能用于发送.必须在创建和启动使用管道的Process对象之前调用Pipe()方法. Pipe()方法返回的Connection对象的实例c具有以下方法和属性. c.clos

Unix IPC之基于共享内存的计数器

目的 本文主要实现一个基于共享内存的计数器,通过父子进程对其访问. 本文程序需基于<<Unix网络编程-卷2>>的环境才能运行.程序中大写开头的函数为其小写同名函数的包裹函数,增加了错误处理信息. 1 函数介绍 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <sys/mman> /**  * Map addresses starting near ADDR an

Unix IPC之共享内存区(1)

1 共享内存区 共享内存区是可用IPC形式中最快的,只有映射和解除映射需要进入内核的系统调用,映射后对共享内存区的访问和修改不再需要系统调用(内核只要负责好页表映射和处理页面故障即可),但通常需要同步手段. 一个客户-服务器间传递文件数据的例子中,FIFO或消息队列等IPC方式通常需要4次内核-进程间的数据复制(但是Posix消息队列可使用内存映射I/O实现,就不一定4次了),每次都需要切换地址空间,开销很大:共享内存区只需要2次跨内核的数据复制. 2  mmap mmap的三个目的: 1.