189 8069 5689

python中的管道函数 python 管道 队列

python stdin 为pipe什么意思

Linux中进程的通信方式有信号,管道,共享内存,消息队列socket等。其中管道是*nix系统进程间通信的最古老形式,所有*nix都提供这种通信方式。管道是一种半双工的通信机制,也就是说,它只能一端用来读,另外一端用来写;另外,管道只能用来在具有公共祖先的两个进程之间通信。管道通信遵循先进先出的原理,并且数据只能被读取一次,当此段数据被读取后,马上会从数据中消失,这一点很重要。

专注于为中小企业提供成都网站制作、成都网站设计服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业琼中黎族免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了千余家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。

Linux上,创建管道使用pipe函数,当它执行后,会产生两个文件描述符,分别为读端和写端。单个进程中的管道几乎没有任何作用,通常会先调用pipe,然后调用fork,从而创建从父进程到子进程的IPC通道。

Linux中,我们经常会使用到管道,例如用cat命令查看一个大文件时,一页不能全部显示,我们可以通过cat xxx | more来分页显示,又比如搜索文件里的内容可以用 cat xxx | grep search来进行,这里我们都用到了管道。接下来我会用python编写一段自动分页显示的程序,而不用手动来使用管道。

#!/usr/bin/env python

import os,sys

if not sys.argv[1:]:

print "No filename input"

sys.exit(1)

try:

fp = open(sys.argv[1],"r")

except IOError,msg:

sys.exit(msg)

pi=os.pipe()

pid=os.fork()

if pid:

#parent

os.close(pi[0]) #close read pipe

#write to pipe

line=fp.readline()

while line:

os.write(pi[1],line)

line=fp.readline()

#close write pipe

os.close(pi[1])

#wait for chile

os.waitpid(pid,0)

else:

os.close(pi[1]) #close write pipe

#put pipe read to stdin

os.dup2(pi[0],sys.stdin.fileno())

os.close(pi[0])

os.execl("/bin/more","more")

把这段代码存为scat.py,增加执行权限之后,运行 scat.py 文件名,系统就会自动读取文件的内容并分页,与使用 cat 文件名 | more 的效果是一模一样的。在上面的代码中,用到了前几篇博客中说的fork,dup2和exec系列函数。

python编程中 os.mkfifo()和os.mknod()函数具体用法?最好有例子,里面参数具体怎么配置就能创建管道或节

mkfifo函数使用

[code]mkfifo(建立实名管道)

相关函数

pipe,popen,open,umask

表头文件

#include

#include

定义函数

int mkfifo(const char * pathname,mode_t mode);

函数说明

mkfifo() 会依参数pathname建立特殊的FIFO文件,该文件必须不存在,而参数mode为该文件的权限(mode%~umask),因此 umask值也会影响到FIFO文件的权限。Mkfifo()建立的FIFO文件其他进程都可以用读写一般文件的方式存取。当使用open()来打开 FIFO文件时,O_NONBLOCK旗标会有影响

1、当使用O_NONBLOCK 旗标时,打开FIFO 文件来读取的操作会立刻返回,但是若还没有其他进程打开FIFO 文件来读取,则写入的操作会返回ENXIO 错误代码。

2、没有使用O_NONBLOCK 旗标时,打开FIFO 来读取的操作会等到其他进程打开FIFO文件来写入才正常返回。同样地,打开FIFO文件来写入的操作会等到其他进程打开FIFO 文件来读取后才正常返回。

返回值

若成功则返回0,否则返回-1,错误原因存于errno中。

错误代码

EACCESS 参数pathname所指定的目录路径无可执行的权限

EEXIST 参数pathname所指定的文件已存在。

ENAMETOOLONG 参数pathname的路径名称太长。

ENOENT 参数pathname包含的目录不存在

ENOSPC 文件系统的剩余空间不足

ENOTDIR 参数pathname路径中的目录存在但却非真正的目录。

EROFS 参数pathname指定的文件存在于只读文件系统内。

示例1:

#include

#include

#include

#include

int main(void)

{

char buf[80];

int fd;

unlink( "zieckey_fifo" );

mkfifo( "zieckey_fifo", 0777 );

if ( fork() 0 )

{

char s[] = "Hello!\n";

fd = open( "zieckey_fifo", O_WRONLY );

write( fd, s, sizeof(s) );

//close( fd );

}

else

{

fd = open( "zieckey_fifo", O_RDONLY );

read( fd, buf, sizeof(buf) );

printf("The message from the pipe is:%s\n", buf );

//close( fd );

}

return 0;

}

执行

hello!

示例2:

#include

#include

#include

#include

#include

int main( int argc, char **argv )

{

mode_t mode = 0666;

if ( argc !=2 )

{

printf( "Usage:[%s] fifo_filename\n", argv[0] );

return -1;

}

if (mkfifo( argv[1], mode)0 )

{

perror( "mkfifo");

return -1;

}

return 0;

} [/code]

Python多进程运行——Multiprocessing基础教程2

上篇文章简单介绍了multiprocessing模块,本文将要介绍进程之间的数据共享和信息传递的概念。

在多进程处理中,所有新创建的进程都会有这两个特点:独立运行,有自己的内存空间。

我们来举个例子展示一下:

这个程序的输出结果是:

在上面的程序中我们尝试在两个地方打印全局列表result的内容:

我们再用一张图来帮助理解记忆不同进程间的数据关系:

如果程序需要在不同的进程之间共享一些数据的话,该怎么做呢?不用担心,multiprocessing模块提供了Array对象和Value对象,用来在进程之间共享数据。

所谓Array对象和Value对象分别是指从共享内存中分配的ctypes数组和对象。我们直接来看一个例子,展示如何用Array对象和Value对象在进程之间共享数据:

程序输出的结果如下:

成功了!主程序和p1进程输出了同样的结果,说明程序中确实完成了不同进程间的数据共享。那么我们来详细看一下上面的程序做了什么:

在主程序中我们首先创建了一个Array对象:

向这个对象输入的第一个参数是数据类型:i表示整数,d代表浮点数。第二个参数是数组的大小,在这个例子中我们创建了包含4个元素的数组。

类似的,我们创建了一个Value对象:

我们只对Value对象输入了一个参数,那就是数据类型,与上述的方法一致。当然,我们还可以对其指定一个初始值(比如10),就像这样:

随后,我们在创建进程对象时,将刚创建好的两个对象:result和square_sum作为参数输入给进程:

在函数中result元素通过索引进行数组赋值,square_sum通过 value 属性进行赋值。

注意:为了完整打印result数组的结果,需要使用 result[:] 进行打印,而square_sum也需要使用 value 属性进行打印:

每当python程序启动时,同时也会启动一个服务器进程。随后,只要我们需要生成一个新进程,父进程就会连接到服务器并请求它派生一个新进程。这个服务器进程可以保存Python对象,并允许其他进程使用代理来操作它们。

multiprocessing模块提供了能够控制服务器进程的Manager类。所以,Manager类也提供了一种创建可以在不同流程之间共享的数据的方法。

服务器进程管理器比使用共享内存对象更灵活,因为它们可以支持任意对象类型,如列表、字典、队列、值、数组等。此外,单个管理器可以由网络上不同计算机上的进程共享。

但是,服务器进程管理器的速度比使用共享内存要慢。

让我们来看一个例子:

这个程序的输出结果是:

我们来理解一下这个程序做了什么:首先我们创建了一个manager对象

在with语句下的所有行,都是在manager对象的范围内的。接下来我们使用这个manager对象创建了列表(类似的,我们还可以用 manager.dict() 创建字典)。

最后我们创建了进程p1(用于在records列表中插入一条新的record)和p2(将records打印出来),并将records作为参数进行传递。

服务器进程的概念再次用下图总结一下:

为了能使多个流程能够正常工作,常常需要在它们之间进行一些通信,以便能够划分工作并汇总最后的结果。multiprocessing模块支持进程之间的两种通信通道:Queue和Pipe。

使用队列来回处理多进程之间的通信是一种比较简单的方法。任何Python对象都可以使用队列进行传递。我们来看一个例子:

上面这个程序的输出结果是:

我们来看一下上面这个程序到底做了什么。首先我们创建了一个Queue对象:

然后,将这个空的Queue对象输入square_list函数。该函数会将列表中的数平方,再使用 put() 方法放入队列中:

随后使用 get() 方法,将q打印出来,直至q重新称为一个空的Queue对象:

我们还是用一张图来帮助理解记忆:

一个Pipe对象只能有两个端点。因此,当进程只需要双向通信时,它会比Queue对象更好用。

multiprocessing模块提供了 Pipe() 函数,该函数返回由管道连接的一对连接对象。 Pipe() 返回的两个连接对象分别表示管道的两端。每个连接对象都有 send() 和 recv() 方法。

我们来看一个例子:

上面这个程序的输出结果是:

我们还是来看一下这个程序到底做了什么。首先创建了一个Pipe对象:

与上文说的一样,该对象返回了一对管道两端的两个连接对象。然后使用 send() 方法和 recv() 方法进行信息的传递。就这么简单。在上面的程序中,我们从一端向另一端发送一串消息。在另一端,我们收到消息,并在收到END消息时退出。

要注意的是,如果两个进程(或线程)同时尝试从管道的同一端读取或写入管道中的数据,则管道中的数据可能会损坏。不过不同的进程同时使用管道的两端是没有问题的。还要注意,Queue对象在进程之间进行了适当的同步,但代价是增加了计算复杂度。因此,Queue对象对于线程和进程是相对安全的。

最后我们还是用一张图来示意:

Python的multiprocessing模块还剩最后一篇文章:多进程的同步与池化

敬请期待啦!


分享标题:python中的管道函数 python 管道 队列
URL链接:http://jkwzsj.com/article/doseedp.html

其他资讯