我是一个多处理新手,
我对线程有所了解,但我需要提高计算速度,希望通过多处理:
示例描述:将字符串发送到线程,更改字符串+基准测试,将结果发送回打印.
Run Code Online (Sandbox Code Playgroud)from threading import Thread class Alter(Thread): def __init__(self, word): Thread.__init__(self) self.word = word self.word2 = '' def run(self): # Alter string + test processing speed for i in range(80000): self.word2 = self.word2 + self.word # Send a string to be altered thread1 = Alter('foo') thread2 = Alter('bar') thread1.start() thread2.start() #wait for both to finish while thread1.is_alive() == True: pass while thread2.is_alive() == True: pass print(thread1.word2) print(thread2.word2)
目前这需要大约6秒钟,我需要它更快.
我一直在研究多处理,找不到与上面代码相同的东西.我认为我所追求的是汇集,但我发现的例子很难理解.我想利用所有核心(8核),multiprocessing.cpu_count()
但我真的只是有关多处理的有用信息,而不足以复制上述代码.如果有人能指出我正确的方向或更好的方向,请提供一个非常感谢的例子.Python 3请
我有一个Python程序,大约需要10分钟才能执行.所以我用Pool
从multiprocessing
加快速度:
from multiprocessing import Pool
p = Pool(processes = 6) # I have an 8 thread processor
results = p.map( function, argument_list ) # distributes work over 6 processes!
Run Code Online (Sandbox Code Playgroud)
它运行起来要快得多.上帝保佑Python!所以我认为就是这样.
但是我注意到,每次我这样做,即使p
超出范围,过程及其相当大的状态仍然存在; 实际上,我创造了一个内存泄漏.这些进程在我的系统监视器应用程序中显示为Python进程,此时不使用CPU,但需要相当大的内存来维护其状态.
池有函数close
,terminate
和join
,我认为其中一个会杀死进程.有谁知道哪个是告诉我的游泳池p
我完成它的最佳方式?
非常感谢你的帮助!
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
int main ()
{
char name[20];
fd_set input_set;
struct timeval timeout;
int ready_for_reading = 0;
int read_bytes = 0;
/* Empty the FD Set */
FD_ZERO(&input_set );
/* Listen to the input descriptor */
FD_SET(0, &input_set);
/* Waiting for some seconds */
timeout.tv_sec = 10; // 10 seconds
timeout.tv_usec = 0; // 0 milliseconds
/* Invitation for the user to write something */
printf("Enter Username: (in 15 seconds)\n");
printf("Time start now!!!\n");
/* …
Run Code Online (Sandbox Code Playgroud) 这可能看起来很奇怪,但我会尝试将其合理化.我目前广泛使用boost.object_pool与shared_ptr一起使用,最近我遇到了一种情况,我需要拍摄当前程序状态的快照,以便进行全尺寸重放/回滚/快进等功能.
所以我不是试图克隆一个对象池在其他地方使用,这显然不会起作用,因为即使我被boost.pool的接口允许这样做(我不是这样),也没有指向块的有效指针在那个新克隆的游泳池里,它只会毫无意义.但我的用例是,如果有重放/回滚需求,我想将其" 粘贴 "回原始池中.
我当然可以手动复制和克隆所有状态,对象和子状态,子对象和子子...然后将它们打包成快照,并希望一切都会正确,但鉴于复杂性,这很容易出错该项目已经有了,并且它要比我直接复制内存慢得多.使用Command模式(或类似物)来实现undo-redo也是不可能的,因为undo-redo机制不是我的意图.
我只是想知道我是否使用顽固的传统C方式从头开始再做项目,而简单的memcpy(snapshot,all_states,size)调用几乎可以完成所有工作.
我还有其他选择吗?是否有任何boost.object_pool实现允许您克隆底层内存区域?在考虑到这种情况的情况下,侵入性地刺激boost.object_pool是一个合理的选择吗?
我有非常高性能的C ++库。我正在考虑编写一个内存池,这样就不必使用global new
和delete
。我读了一些书。但是想知道这将有助于我减少性能和内存泄漏。
如果我在Python解释器中创建一个具有令人无法接受的大量进程的池,它显然会出现错误,但是在执行此操作之前看起来似乎没有清除分叉进程,因此会使环境变脏,并且系统的其余部分无法分叉进程.
>>> from multiprocessing import Pool
>>> p = Pool(1000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/__init__.py", line 232, in Pool
return Pool(processes, initializer, initargs, maxtasksperchild)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 159, in __init__
self._repopulate_pool()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 222, in _repopulate_pool
w.start()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/process.py", line 130, in start
self._popen = Popen(self)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/forking.py", line 121, in __init__
self.pid = os.fork()
OSError: [Errno 35] Resource temporarily unavailable
>>> p = Pool(1)
Traceback (most recent call last):
File …
Run Code Online (Sandbox Code Playgroud) 更新
根据评论,答案和其他研究,我得出的结论是set
,map
在节点开销方面,a 和a 之间通常没有区别。我的以下问题确实是:
如何确定节点开销以方便
boost::pool_allocator
用作自定义分配器?
而且,进一步的更新:节点的开销大概是永远不会超过4个三分球的大小,所以只是清除了Boost池为sizeof(T)
,sizeof(T)+sizeof(int)
,sizeof(T) + 2*sizeof(int)
,sizeof(T) + 3*sizeof(int)
和sizeof(T) + 4*sizeof(int)
(或int64_t
64位系统)应罚款。那就是我实际上在做的,并且有效。
我想通过避免调用这些对象的析构函数,而不是在每条包含多个实例的单个条带中释放内存,来使用增强内存池来管理数千万个大小相同的微小对象。
我发布了关于此问题的另一个问题,这个问题的答案使我明白,我真正需要回答的问题就是我在这里问的那个问题。
考虑以下代码:
class Obj { // ... has an operator<() ... };
typedef std::set<Obj, std::less<Obj>, boost::fast_pool_allocator<Obj>> fast_set_obj;
// Deliberately do not use a managed pointer -
// I will *NOT* delete this object, but instead
// I will manage …
Run Code Online (Sandbox Code Playgroud) 我知道:
对于无状态会话Bean,服务器可以在池中维护可变数量的实例。每次客户端请求这样的无状态Bean(例如通过方法)时,都会选择一个随机实例来满足该请求。
我的问题是:为什么需要一个游泳池?EJB无状态bean的一个实例是否足以满足所有请求?
同样,如果给定的无状态Bean的服务器使用的是10个实例的池,那么它可以在这种Bean上处理的最大请求数是10吗?
你能帮我解决我的疑问吗?
编辑:
ejb 3.1规范的第4.3.14节给出了答案。
4.3.14序列化会话Bean方法以下要求适用于无状态和有状态会话Bean。有关Singleton会话Bean并发性要求,请参见第4.8.5节。
容器将对每个有状态和无状态会话Bean实例的调用序列化。大多数容器将支持许多并发执行的会话bean实例。但是,每个实例只能看到序列化的方法调用序列。因此,有状态或无状态会话bean不必编码为可重入。
容器必须序列化所有容器调用的回调(即,业务方法拦截器方法,生命周期回调拦截器方法,超时回调方法,beforeCompletion等),并且必须使用客户端调用的业务方法调用来序列化这些回调。 。
在网上稍作搜索,我的疑问是,对于要求EJB无状态方法是线程安全的规范来说,线程池是必需的。因此,如果说池中有10个bean,则只能同时处理10个请求,另一个将排队并分配给第一个空闲bean。如果我错了,请纠正我。
这是一个完整简单的工作示例
import multiprocessing as mp
import time
import random
class Foo:
def __init__(self):
# some expensive set up function in the real code
self.x = 2
print('initializing')
def run(self, y):
time.sleep(random.random() / 10.)
return self.x + y
def f(y):
foo = Foo()
return foo.run(y)
def main():
pool = mp.Pool(4)
for result in pool.map(f, range(10)):
print(result)
pool.close()
pool.join()
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
我怎样才能修改它,所以Foo只被每个工人初始化一次,而不是每个任务?基本上我想要初始化调用4次,而不是10次.我使用的是python 3.5
python pool object-initializers python-multiprocessing python-3.5
我正在尝试使用multiprocessing.Pool
来实现多线程应用程序。要共享一些变量,我在这里使用Queue
提示:
def get_prediction(data):
#here the real calculation will be performed
....
def mainFunction():
def get_prediction_init(q):
print("a")
get_prediction.q = q
queue = Queue()
pool = Pool(processes=16, initializer=get_prediction_init, initargs=[queue,])
if __name__== '__main__':
mainFunction()
Run Code Online (Sandbox Code Playgroud)
该代码可以在Debian计算机上完美运行,但在另一台Windows 10设备上则根本无法运行。它因错误而失败
AttributeError: Can't pickle local object 'mainFunction.<locals>.get_prediction_init'
Run Code Online (Sandbox Code Playgroud)
我真的不知道到底是什么引起了错误。如何解决该问题,以便我也可以在Windows设备上运行代码?
编辑:如果我get_predediction_init
在与相同的级别上创建函数,则可以解决问题mainFunction
。仅当我将其定义为内部函数时,它才失败。对不起,我的帖子混乱。