文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>进程之间之管道通信问题

进程之间之管道通信问题

时间:2009-02-28  来源:zjutlyp

    作为shell设施,管道为linux用户所熟知,如:要显示一个登录用户的排序列表,可以输入如下命令:
    $ who | sort | more
    这就是一个由三个进程两个管道构成的命令。下面我们对管道的操作以及相关应用问题进行探讨。
1、pipe--建立管道
#include <unistd.h>
int pipe(
    int pfd[2]                 /* file descriptor */
);
    该系统调用用来创建一个管道,向pfd[1]中写数据是往管道输入数据,从pfd[0]读是从管道中读数据。读写操作和普通文件相同,但有别于一般文件的读,读管道是不可逆的,一旦读取了,就不可以重新读。
2、dup和dup2--复制文件描述符 int dup(int fd);
int dup2(int fd, int fd2);
    复制一个现有的文件描述符,可以得到另一个新的、指向同一个文件的描述符;dup2调用主要用于将文件描述符指定为特定的描述符,如dup2(fd, STDIN_FILENO);
3、非重定向管道的双向通信
    假设现在我们要利用管道把数据传递给sort进程,同时从管道读取sort输出的已经排序好的数据。下面给出一个实现,并对其中的问题进行分析:
void fsort(void)
{
    int pfd[2], fd;
    ssize_t nread;
    pid_t pid;
    char buf[512];
    pipe(pfd);
    pid = fork();
    switch (pid) {
    case -1:
        exit(1);
    case 0:
        dup2(pfd[0], STDIN_FILENO);
        close(pfd[0]);
        dup2(pfd[1], STDOUT_FILENO);
        close(pfd[1]);
        execlp("sort", "sort", (char *)NULL);
        exit(1);
    default:
        fd = open("datafile", O_RDONLY);
        while (1) {
            nread = read(fd, buf, sizeof(buf));
            if (nread == 0)
                break;
            write(pfd[1], buf, nread);
        }
        close(pfd[1]);
        close(fd);
        while (1) {
            nread = read(pfd[0], buf, sizeof(buf));
            if (nread == 0)
                break;
            write(STDOUT_FILENO, buf, nread);
        }
        close(pfd[0]);
        waitpid(pid, NULL, 0);
        return ;
    }
}
    运行程序,结果程序原样输出,这是因为父进程刚把数据输入管道,而这个时候子进程还未来得及读取其中相关的数据,父进行已经开始对管道进行读操作,所以读取的数据还是原来输入管道的数据。
    另一个问题是会引起死锁,因为对于子进程来说,它的读取操作是一直进行到文件结尾,虽然父进程是已经关闭了写文件描述符,但子进程来说它还是打开的,这样子进程一直等待文件结尾形成死锁。其解决方案是采用两个管道,一个管道控制由应用程序向sort进程输出,另一个管道控制应用程序从sort进程读。但是使用两个管道同样可能产生死锁,如果输出管道满了,而子进程没有去清空它,而是写回足够的输出给父进程以至于阻塞另一管道,父、子进程均会阻塞写输出管道而形成死锁。
4、交互式问题
    这里说一个很简单的例子,子进程是标准文本编辑器。父进程把编辑器作为服务器向它发送编辑命令行,并得到输出。可视化界面可能会安排由父进程控制键盘和屏幕,而让ed做具体的编辑工作。工作的时候就是父进程向子进程发送一些数据,子进程通过一定的处理,返回一些数据给父进程。在这里就涉及到一个问题是父进程一次性发送的数据什么时候结束。和前面的不同之处在于前面所涉及的问题中数据的结束是文件的结尾。而在这里是不知道的。如果数据读得太多会产生死锁,如果读得太少,将失去命令和它的结果间的同步。
    这时候可以通信协议就派上了用场,定义数据帧,一帧一帧数据的传送。两进程通信可以参考串口双机通信。
相关阅读 更多 +
排行榜 更多 +
爱是小事最新版

爱是小事最新版

休闲益智 下载
悬案2刹那惊颤游戏

悬案2刹那惊颤游戏

冒险解谜 下载
几何飞行内购修改版

几何飞行内购修改版

飞行射击 下载