前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用Python操作Named pipe命

用Python操作Named pipe命

作者头像
py3study
发布2020-01-07 11:17:22
1.8K0
发布2020-01-07 11:17:22
举报
文章被收录于专栏:python3python3

        在我以前做过的用于手游服务器的Python服务器框架里,我用了Python的multiprocessing库,多进程通信用了multiprocessing提供的最方便的queue,实际上就是一种匿名管道。要求管道两端的进程必须是父子进程或者兄弟进程。

        匿名管道给后续扩展带来影响,无法动态的增加或者减少服务进程。如果可以动态增加减少进程,至少在非严重故障时重启服务器会方便很多。

       之前研究了一阵命名管道,遇到很多问题。这两天有空再次试验,想明白了很多。直接看例子。

客户端  Client.py:

代码语言:javascript
复制
# named pipe Client
#encoding: utf-8

import os
import time

write_path = "/tmp/server_in.pipe"
read_path = "/tmp/server_out.pipe"

counter = 1

f = os.open( write_path, os.O_SYNC | os.O_CREAT | os.O_RDWR )
print "Client open f", f

rf = None

while True:
    # Client发送请求
    req = "%s "%counter 
    len_send = os.write( f, req )
    print "request", req, len_send

    counter += 1
    
    if rf == None:
        # *要点1:在这里第一次打开read_path,实际这里的open是一个阻塞操作
        # 打开的时机很重要。如果在程序刚开始,没发送请求就打开read_path,肯定会阻塞住
        rf = os.open( read_path, os.O_RDONLY )
        print "client opened rf", rf

    # 接收Server回应
    s = os.read( rf, 1024 )
    if len(s) == 0:
        # 一般来说,是管道被意外关闭了,比如Server退出了
        break

    print "received", s

    # 这个例子里没有sleep,客户端以最高速度发送数据,可以观察执行效果


os.close( f )
os.close( rf )

服务器  Server.py:

代码语言:javascript
复制
#named pipe Server
#encoding: utf-8

import os, time

read_path = "/tmp/server_in.pipe"
write_path = "/tmp/server_out.pipe"

try:
    # 创建命名管道
    os.mkfifo( write_path )
    os.mkfifo( read_path )
except OSError, e:
    # 如果命名管道已经创建过了,那么无所谓
    print "mkfifo error:", e

# 写入和读取的文件,正好和Client相反
rf = os.open( read_path, os.O_RDONLY )
f = os.open( write_path, os.O_SYNC | os.O_CREAT | os.O_RDWR )

while True:
    # 接收请求
    s = os.read( rf, 2 )
    if len(s) == 0:
        # 没有收到字符,一般是唯一的发送方被关闭了。
        # 这里可以休息一下继续,对后续消息没有任何影响,也不会丢包。
        time.sleep( 1 )
        continue

    # 如果收到的字符串带一个s,打印出来
    # 用于调试和测试
    if "z" in s:
        print "received", s

    # 在请求前面加一个s字母,返回
    os.write( f, "s%s"%s )

os.close( f )
os.close( rf )

        这个例子具有一定实用性:

        1、无论先执行Server.py还是Client.py都可以正常工作。

        2、Server.py与Client.py执行时,可以在另一个控制台里输入   echo zzzzz > /tmp/server_in.pipe,可以观察到,server可以同时处理多个来源的请求

        3、实际上在进程交互时,每个进程既是一个Client又是一个Server,每个进程只有一个用于接收别人请求的pipe,然后接收请求后把处理结果返回给发送方的pipe。这样网络就联系起来了。和匿名管道的架构是一致的。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档