169it科技资讯


当前位置:  技术问答>linux和unix

Linux中管道的使用(父或子进程中能否都保留读写端)

    来源: 互联网  发布时间:2017-01-12

最近在看管道相关的操作,管道可用于父子进程间的IPC。
通常情况下,数据流是单向的(半双工),如对于父->子的管道,在父进中要关闭读端(fd[0]),子进程中关闭写端(fd[1])。对于子->父的管道,在父进中要关闭写端(fd[1]),子进程中关闭读端(fd[0])。

我的问题是,能否在父子进程中对于读写端都不关闭,从而可以实现父子的全双工通讯。

我写了简单的测试代码,输出为:
C
P
kkkkkkkkkkkk

用sleep进行延时,让子进程先执行,由输出看确实先输出了"C",但为何这时,在父进程中的write(fd[1], "tttttt", 6);无效呢?

code:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
int fd[2];
pid_t pid;
char get[13];
if(pipe(fd) < -1){
printf("Pipe Error!\n");
return -1;
}
if((pid = fork()) < 0){
printf("Fork Error!\n");
return -1;
}else if(pid > 0){
/* parent */
sleep(1);
printf("P\n");
write(fd[1], "tttttt", 6);
read(fd[0], get, 12);
get[12] = '\0';
printf("read: %s\n", get);
}else{
/* child */
printf("C\n");
write(fd[1], "kkkkkkkkkkkk", 12);
}

}




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

void alrmFunc(int signo)
{
        printf("alarm\n");
        exit(2);
}

void chldFunc(int signo)
{
        pid_t pid;

        while(true)
        {
                pid=waitpid(-1,NULL,WNOHANG);

                if(pid==0)
                {
                        break;
                }
                else if(pid<0)
                {
                        if(errno==ECHILD)
                        {
                                break;
                        }
                }
                else
                {
                        printf("pid:%d exit!\n",pid);
                }
        }
}

int main(int argc, char **argv)
{
    int fd[2];
    pid_t pid;
    char get[13];

        if(signal(SIGCHLD,chldFunc)==SIG_ERR)
        {
                perror("signal");
                exit(1);
        }

    if(pipe(fd) < -1){
        printf("Pipe Error!\n");
        return -1;
    }
    if((pid = fork()) < 0){
        printf("Fork Error!\n");
        return -1;
    }else    if(pid > 0){
        /* parent */
                if(signal(SIGALRM,alrmFunc)==SIG_ERR)
                {
                        perror("signal");
                        exit(1);
                }

        printf("P\n");
        write(fd[1], "tttttt", 6);
                int n;

                alarm(3);

        while( (n=read(fd[0], get, 12))>0 )
                {
                        get[n]='\0';
                        printf("%s",get);
                        fflush(stdout);
                }
                //父进程读光父子进程所有数据
                //但是父进程阻塞在read,没法close pipe[1]
                //所以read也得不到EOF,这就是很纠结的一件事了
                //设置read非阻塞说不定运气不好数据没读全就EAGAIN了
                //可以使用select pipe[0],设置一个超时值,超时则关闭pipe[1]退出
                //这里我在alarm里退出父进程
                printf("parent exit\n");
                //让父进程退出自动关闭pipe[0] and pipe[1]
    }else{
        /* child */
        printf("C\n");
        write(fd[1], "kkkkkkkkkkkk", 12);
    }

        //子进程退出自动关闭pipe[1],pipe[0].
    //但子进程不是唯一的pipe[1]持有者,所有不发送EOF
        return 0;
}

|
子进程完了后,应该通知父进程吧?是不是应该加以个通知?

|

这样是不行的,当父进程和子进程都从一个pipe中读操作,读出来的可能是自己刚刚写进去的。
如果你想全双工的话,使用两个pipe就好了。
本页相关标签:

    
相关技术文章:
    ▪怎样用C代码创建linux电子表格

     我现在希望能用C或C++代码创建一个电子表格不限定具体是哪个office,不过我看openoffice好像在linux里用的多,然后创建后往表格里写内容 | 没人回答 ......


    ▪在linux中是不是能看到设备节点就说明设备可以被访问了

     我的USB设备现在可以看到/proc/bus/usb/001/008的可是在下面的访问的时候总是不行,求助大家帮忙看下问题在哪 芯片:CY7C68013 系统:企业版Redhat5以上 下面是用libusb1.0的部分代码 libusb_get_device_list可以看到所有usb设备,本设备信息Number of possible configurations: 1 Device Class: 0 VendorID: 1607 ProductID: 4098Interfaces: 1 ||| Number of alternate settings: 1 | Interface Number: 0 | Number of endpoints: 2 | Descriptor Type: 5 | EP Address: 130 | Descriptor Type: 5 | EP Address: 134 |  可根据上面的VendorID: 1607 ProductID: 4098   用./getdevpath -v647 -p1002 查到/proc/bus/usb/001/008,......


    ▪如何增加linux虚拟机文件系统空间

     如何增加linux虚拟机文件系统空间。我安装虚拟机的时候分配的是8G的空间,现在不够用了,我将物理空间增大到30G了但是df命令查看时显示还是8G。 请问如何增加?谢谢 | 你是增加的硬盘吗? 需要将新的空间进行分区,格式化; 用cfdisk命令分区,然后把新的分区挂载到你要的路径就可以了,大体是这样,google吧 | 你分区的时候考虑的不周全,现在就很费劲了 如果你的/是用的虚拟文件系统,那比较容易扩充 如果不是,而且只分了一个/出来,那就要先看一下你哪些目录占的空间太大了 一般......


 
最新技术文章:
    ▪linux编写一个脚本判断程序是否在运行,如果没运行就重启这

     RT 先谢过大家了。 | processExist=`ps aux|grep processName|grep -v "grep" ` if [ -z $processExist ];then     exec processName else     echo "process is running" fi | 正解 | 版主所言甚对 ......


    ▪求高手解决国嵌视频中课程1-Linux系统管理,NFS网络配置问题

     下面是出现的问题 [root@localhost /]#service portmap start bash: service: command not found [root@localhost /]# /etc/rc.d/init.d/portmap start  starting portmap:                                  [OK] [root@localhost /]# /etc/rc.d/init.d/nfs start     [OK] Starting NFS services:                             [OK] Starting NFS  quotas:                              [OK] Starting NFS  daemon:                              [FAILED] 下面是我的NFS设置 root@localhost /]# vi /etc/exports /home 192.168.1.230(rw,sync,no_root_squash) 问题1......


    ▪软链接不能修改?只能删除,然后重建?

     RT | ln -f 试试 | 可以修改 就是强制覆盖 ln -sf xxx yyy | 使用-f选项,强制覆盖 | +++ ......


 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2017,169IT.COM,E-mail:www_169it_com#163.com(请将#改为@)

浙ICP备11055608号