Python多处理Pool.apply_异步具有共享变量(值)

2024-10-02 00:41:58 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的大学项目中,我正在尝试开发一个基于python的流量生成器,我在vmware上创建了2台CentOS机器,我使用1作为我的客户机,1作为我的服务器机器。我使用了IP aliasing技术来增加仅使用单个客户机/服务器机器的客户机和服务器的数量。到目前为止,我已经在我的客户机上创建了50个IP别名,在我的服务器机器上创建了10个IP别名。我还使用多处理模块同时生成从所有50个客户端到所有10个服务器的流量。我还在我的服务器上开发了一些配置文件(1kb、10kb、50kb、100kb、500kb、1mb)(因为我在使用Apache服务器,所以我在/var/www/html目录下)并使用urllib2从客户机向这些概要文件发送请求。我使用httplib+urllib2首先绑定到任何一个源别名ip,然后使用urllib2从该ip发送请求。这里是increase my number of TCP Connections,我正在尝试使用multiprocessing.Pool.apply\u异步模块。但是在运行脚本时,我遇到了一个错误“RuntimeError:Synchronized objects should be shared between processes through inheritation”(运行时错误:同步对象只能通过继承在进程之间共享)。经过一番调试,我发现这个错误是由于使用多处理.值. 但是我想在我的进程之间共享一些变量,我还想增加TCP连接的数量。其他模块(除了多处理.值)可以在这里共享一些公共变量吗?或者,对于这个查询还有其他解决方案吗?在

'''
Traffic Generator Script:

 Here I have used IP Aliasing to create multiple clients on single vm machine. 
 Same I have done on server side to create multiple servers. I have around 50 clients and 10 servers
'''
import multiprocessing
import urllib2
import random
import myurllist    #list of all destination urls for all 10 servers
import time
import socbindtry   #script that binds various virtual/aliased client ips to the script
m=multiprocessing.Manager()
response_time=m.list()    #some shared variables
error_count=multiprocessing.Value('i',0)
def send_request3():    #function to send requests from alias client ip 1
    opener=urllib2.build_opener(socbindtry.BindableHTTPHandler3)    #bind to alias client ip1
    try:
        tstart=time.time()
        for i in range(myurllist.url):
            x=random.choice(myurllist.url[i])
            opener.open(x).read()
            print "file downloaded:",x
            response_time.append(time.time()-tstart)
    except urllib2.URLError, e:
        error_count.value=error_count.value+1
def send_request4():    #function to send requests from alias client ip 2
    opener=urllib2.build_opener(socbindtry.BindableHTTPHandler4)    #bind to alias client ip2
    try:
        tstart=time.time()
        for i in range(myurllist.url):
            x=random.choice(myurllist.url[i])
            opener.open(x).read()
            print "file downloaded:",x
            response_time.append(time.time()-tstart)
    except urllib2.URLError, e:
        error_count.value=error_count.value+1
#50 such functions are defined here for 50 clients
def func():
    pool=multiprocessing.Pool(processes=750)
    for i in range(5):
        pool.apply_async(send_request3)
        pool.apply_async(send_request4)
        pool.apply_async(send_request5)
#append 50 functions here
    pool.close()
    pool.join()
    print"All work Done..!!"
    return
start=float(time.time())
func()
end=float(time.time())-start
print end

Tags: toimport服务器clientsendfor客户机time
2条回答

可能,因为 Python Multiprocess diff between Windows and Linux (我说真的,我不知道多处理在vm中是如何工作的,就像这里的情况一样。)

这可能有用

^{1}$

如错误消息所述,您不能通过pickle传递multiprocessing.Value。但是,您可以使用^{}

^{1}$

以下是一些其他注意事项:

  1. 在750个进程中使用Pool不是一个好主意。除非你使用的服务器有数百个CPU核心,否则你的机器就会被它压垮。使用更少的过程会更快,对机器的压力更小。更像2 * multiprocessing.cpu_count()。在
  2. 作为最佳实践,您应该显式地将需要使用的所有共享参数传递给子进程,而不是使用全局变量。这增加了代码在Windows上运行的可能性。在
  3. 看起来所有的send_request*函数的作用几乎完全相同。为什么不创建一个函数并使用一个变量来决定使用哪个socbindtry.BindableHTTPHandler?这样做可以避免代码重复。在
  4. 递增error_count的方式不是进程/线程安全的,而且容易受到竞争条件的影响。您需要使用锁来保护增量(正如我在上面的示例代码中所做的那样)。在

相关问题 更多 >

    热门问题