python linux 管道读写通讯阻塞

管道一直是进程间的通讯的重要方式。

首先我要说一下进程通讯之间为什么会需要管道,因为进程之间的内存是独立的,我为什么这么说呢,好多人都只知道fork却不知道所以然,众所周知,fork之后会出现子进程,但是我就问你是否考虑过父子进程的内存关系,其实fork中的子进程是对fork之前的主进程的内存的一个复制,然后,拼接到pid==0的内存,形成一个内存空间,好如果我们在for循环里循环4个子进程,那么每一个子进程的内存绝对都是独立的,我们没有办法去达到进程的内存公用,我们这里有几个方案,共享内存(或者以mmap实现共享内存),或者使用消息队列,信号量或者使用管道进行通讯,传递一些比较重要的东西,比如说文件描述符这一类的东西,所以我们在进程通讯的时候要使用管道

但是在读写中会产生阻塞,对于许多异步程序会产生很严重的影响,为此我们需要把管道设置为非阻塞的 在之前我学习管道的思路一直是pipe创建完管道后直接fork出现子进程,然后父进程这里在用管道读,子进程用管道写,但是问题就是会出现阻塞!但是linux c中可以用poll来解决,由于只有两个文件描述符读和写所以我们完全没有必要去使用epoll做边缘触发,直接使用poll做轮循就可以,毕竟只有2个文件描述符嘛

c语言中我们可以采用poll来解决这个问题

int poll(struct pollfd *fds,nfds_t nfds, int timeout);

设置完成超时时间后我们可以很快中断操作,避免发生阻塞使程序继续执行,由于我写的是python所以也可以这么处理

import os
import select
class WorkPipe:


    read = None
    write = None
    READ_ONLY = select.POLLIN
    READ_WRITE = select.POLLOUT

    #create pipe
    def createWorker_pipe(self):
        r,w = os.pipe()
        self.read = r
        self.write = w
        pass

    #write pipe
    def readWorker_pipe(self):
        # os.close(self.write)

        if(self.pipe_wait(self.read,self.READ_ONLY) == True):
            pipeOpenHandel = os.fdopen(self.read)
            readContent = pipeOpenHandel.read()
            return readContent
            pass
        return ""
        pass

    #write pipe
    def writeWorker_pipe(self,socketfd):
        # os.close(self.read)
        if (self.pipe_wait(self.write, self.READ_WRITE) == True):
            pipeWriteHandel = os.fdopen(self.write, 'w')
            pipeWriteHandel.write(str(socketfd) + "&")
            return True
            pass
        return False
        pass

    def pipe_wait(self,fd,type):
        poller = select.poll()
        poller.register(fd, type)
        result = poller.poll(1)
        if(len(result) > 0):
            return True
        else:
            return False
        pass

    pass

但是由于是非阻塞的所以我不主张关闭文件描述符,关闭文件描述符程序可能在轮循中报错

猜你喜欢

转载自blog.csdn.net/qq_32783703/article/details/80114492