我正在尝试制作一个多处理 MongoDB 实用程序,它完美地工作,但我认为我有一个性能问题......即使有 20 个工人,它每秒处理的文档也不超过 2800 个......我想我可以得到快 5 倍...这是我的代码,它没有做任何异常的事情,只是将剩余时间打印到光标的末尾。
也许有更好的方法在 MongoDB 游标上执行多处理,因为我需要在每个包含 17.4M 记录集合的文档上运行一些东西,所以性能和更少的时间是必须的。
START = time.time()
def remaining_time(a, b):
if START:
y = (time.time() - START)
z = ((a * y) / b) - y
d = time.strftime('%H:%M:%S', time.gmtime(z))
e = round(b / y)
progress("{0}/{1} | Tiempo restante {2} ({3}p/s)".format(b, a, d, e), b, a)
def progress(p, c, t):
pc = (c * 100) / t
sys.stdout.write("%s [%-20s] %d%%\r" % (p, '?' * (pc / 5), pc))
sys.stdout.flush()
def …Run Code Online (Sandbox Code Playgroud) python GIL的存在是否意味着在python多线程中,相同的操作与在单个线程中重复它没有那么不同?
例如,如果我需要上传两个文件,那么在两个线程中执行它们的优势是什么,而不是一个接一个地上传它们?
我尝试了两种方式的大数学运算.但他们似乎花了几乎相同的时间来完成.
这似乎对我来说不清楚.有人可以帮我吗?谢谢.
免责声明:我对多线程非常糟糕,所以我完全有可能做错了.
我在Python中编写了一个非常基本的光线跟踪器,我一直在寻找可能加速它的方法.多线程似乎是一种选择,所以我决定尝试一下.但是,虽然原始脚本需要大约85秒来处理我的示例场景,但多线程脚本最终需要大约125秒,这看起来非常不直观.
这是原始的样子(我不会复制绘图逻辑和东西.如果有人认为需要找出问题,我会继续把它放回去):
def getPixelColor(x, y, scene):
<some raytracing code>
def draw(outputFile, scene):
<some file handling code>
for y in range(scene.getHeight()):
for x in range(scene.getWidth()):
pixelColor = getPixelColor(x, y, scene)
<write pixelColor to image file>
if __name__ == "__main__":
scene = readScene()
draw(scene)
Run Code Online (Sandbox Code Playgroud)
这是多线程版本:
import threading
import Queue
q = Queue.Queue()
pixelDict = dict()
class DrawThread(threading.Thread):
def __init__(self, scene):
self.scene = scene
threading.Thread.__init__(self)
def run(self):
while True:
try:
n, x, y = q.get_nowait()
except Queue.Empty:
break
pixelDict[n] = getPixelColor(x, y, …Run Code Online (Sandbox Code Playgroud) 我使用 2 个 python 进程,我想知道如何共享和更新变量。我设法将变量发送到进程,但该变量在进程期间没有更新。
在我的代码中,当进程worker启动时,它每 3 秒增加一次变量a。同时这个过程my_service不断展现出价值a。
#!/usr/bin/python
# -*- coding: utf-8 -*-
#import multiprocessing as mp
#from multiprocessing import Process
import multiprocessing
import time
from globalvar import *
a=8
#toto=8
def worker():
name = multiprocessing.current_process().name
# print (name,"Starting")
# time.sleep(2)
# print (name, "Exiting")
for a in range(1,4):
print ("worker=",a)
time.sleep(3)
def my_service(az):
name = multiprocessing.current_process().name
# print (name,"Starting")
# time.sleep(3)
# print (name, "Exiting")
while True:
print ("my_service=",az)
time.sleep(2) …Run Code Online (Sandbox Code Playgroud) 即使我没有给出 gtkMainLoop.start() 函数调用,下面的代码也会在声明 og gtkLoopTHread 本身后受到攻击。我想在后台运行计时器,并在该 UI 中执行一些操作,并在计时器达到“0”时销毁 UI。
代码
def createCountDown(maxSec):
while maxSec > 0:
print maxSec;
maxSec = maxSec - 1;
gtk.main_quit();
return;
maxSec = 5;
gtkLoopThread = threading.Thread(group=None, target=gtk.main, name=None, args=(), kwargs={});
print "After gtkThread declaration"
myThread = threading.Thread(group=None, target=createCountDown, name=None, args=(maxSec), kwargs={});
gtkLoopThread.start();
myThread.start();
Run Code Online (Sandbox Code Playgroud)
预期输出:
After gtkThread declaration
5
4
3
2
1
Run Code Online (Sandbox Code Playgroud)
当前行为: 行“在 gtkThread 声明之后”没有看到打印,因为 gtkLoopThread 在初始化 gtkLoopThread 变量后立即启动
之前我尝试使用python中的threading模块来创建多个线程。然后我了解了GIL以及它如何不允许在一台机器上利用多个 CPU 内核。所以现在我正在尝试进行多处理(我并不严格需要单独的线程)。
这是我编写的示例代码,用于查看是否正在创建不同的进程。但是从下面的输出中可以看出,我每次都得到相同的进程 ID。所以没有创建多个进程。我错过了什么?
import multiprocessing as mp
import os
def pri():
print(os.getpid())
if __name__=='__main__':
# Checking number of CPU cores
print(mp.cpu_count())
processes=[mp.Process(target=pri()) for x in range(1,4)]
for p in processes:
p.start()
for p in processes:
p.join()
Run Code Online (Sandbox Code Playgroud)
输出:
4
12554
12554
12554
Run Code Online (Sandbox Code Playgroud) 是否有一种快速的方法来设置python中的函数将来某个时间执行(非阻塞,类似于Javascript中的setTimeout)?我知道如何自己做,但如果它在库中,我宁愿使用已经完成的东西.
我正在使用 python 将许多记录添加到 Postgres DB 中,因为我必须插入数百万条记录,我需要并行化 2 个函数:
insert_A(cur)
insert_B(cur)
Run Code Online (Sandbox Code Playgroud)
在哪里:
conn=psycopg2.connect(.....)
cur = conn.cursor()
Run Code Online (Sandbox Code Playgroud)
我尝试了在堆栈溢出的另一篇文章中找到的解决方案,例如:
result1= pool.apply_async(insert_A, cur)
result2= pool.apply_async(insert_B, cur)
answer1=result1.get(timeout=15)
answer2=result2.get(timeout=15)
Run Code Online (Sandbox Code Playgroud)
但我收到此错误: Traceback (most最近一次调用最后):
File "test.py", line 387, in
answer1=result1.get(timeout=15)
File "/Library/Frameworks/Python.framework/Versions/2.7/ lib/python2.7/multiprocessing/pool.py",第 558 行,在 get
raise self._value
psycopg2.InterfaceError:光标没有连接
有人可以帮助我吗?:(
python incrementf就是这样定义的
#define Py_INCREF(op) ( \
_Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \
((PyObject *)(op))->ob_refcnt++)
Run Code Online (Sandbox Code Playgroud)
对于多核,增量只是L1高速缓存而不是刷新到内存.
如果两个线程同时递增refcnt,在不同的核心中,没有刷新到实际内存,对我来说,可能会丢失一个增量. - ob_refcnt = 1 - 核心1增量,但不冲水=> ob_refcnt = 2在芯体1的L1高速缓存 - 核心2增量,但不冲水=> ob_refcnt = 2在芯2的L1高速缓存 - WTF
使用多核或多进程是否存在风险?
PyObject声明如下:
typedef struct _object {
_PyObject_HEAD_EXTRA
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
} PyObject
Run Code Online (Sandbox Code Playgroud)
但是Py_ssize_t只是一个ssize_t或intptr_t.
似乎没有使用_Py_atomic*函数和属性.
Python如何管理这种情况?它如何刷新线程之间的缓存?
我写了这样的代码:
def process(data):
#create file using data
all = ["data1", "data2", "data3"]
Run Code Online (Sandbox Code Playgroud)
我想在我的所有列表上并行执行进程函数,因为它们正在创建小文件,所以我不关心磁盘写入,但处理需要很长时间,所以我想使用我的所有内核。
如何使用 python 2.7 中的默认模块执行此操作?
python ×9
gil ×1
gtk ×1
mongodb ×1
postgresql ×1
psycopg2 ×1
pygtk ×1
python-2.7 ×1
variables ×1