python GIL的存在是否意味着在python多线程中,相同的操作与在单个线程中重复它没有那么不同?
例如,如果我需要上传两个文件,那么在两个线程中执行它们的优势是什么,而不是一个接一个地上传它们?
我尝试了两种方式的大数学运算.但他们似乎花了几乎相同的时间来完成.
这似乎对我来说不清楚.有人可以帮我吗?谢谢.
我想在网上提供一个人们可以测试算法性能的服务,这是用python编写并在linux机器上运行的
基本上我想做的是,有一个非常简单的PHP处理程序,比方说start_algo.php,它接受来自浏览器的请求,以及通过system()或popen()的php代码(类似于exec(" python algo.py"))发出一个运行python脚本的新进程,我认为这部分是可行的
问题是,因为它是一个Web服务,当然它必须同时为多个用户服务,但我很困惑的全球解释器锁GIL http://wiki.python.org/moin/GlobalInterpreterLock '标准'CPython已实现,是否意味着,如果我有3个用户现在运行算法(这意味着3个独立的进程,如果我错了,请纠正我),在特定时刻,只有一个用户正在运行Python口译员和其他2人正在等待轮到他们?
提前谢谢了
摊晒
为什么math.factorial在一个线程中表现得如此奇怪?
这是一个例子,它创建了三个线程:
它调用start线程,然后join超时
睡眠和旋转线程按预期工作并立即返回start,然后坐在join超时.
另一方面,析取线程start直到它运行到最后才返回!
import sys
from threading import Thread
from time import sleep, time
from math import factorial
# Helper class that stores a start time to compare to
class timed_thread(Thread):
def __init__(self, time_start):
Thread.__init__(self)
self.time_start = time_start
# Thread that just executes sleep()
class sleep_thread(timed_thread):
def run(self):
sleep(15)
print "st DONE:\t%f" % (time() - time_start)
# Thread that increments a number for a while …Run Code Online (Sandbox Code Playgroud) 我正在分析一些多线程CPython代码.
为了测量它需要执行特定代码段的时间,我想迫使GIL(全局解释器锁),以不为段线程之间切换.如何才能做到这一点?
更新:
假设以下伪代码:
some_code_1()
make_the_interpreter_not_change_thread()
take_start_time() # time critical
code_to_profile() # time critical
take_end_time() # time critical
release_the_interpreter()
some_code_2()
Run Code Online (Sandbox Code Playgroud)
我担心的是,解释器将在"时间关键"分析期间切换线程.
所以我目前正在尝试做一些像A**b这样的东西用于一些2d ndarray和一个双b并行用于Python.我想使用OpenMP进行C扩展(是的,我知道,有Cython等等但是在某些时候我总是遇到那些'高级'方法的麻烦......).
所以这里是我的gaussian.so的gaussian.c代码:
void scale(const double *A, double *out, int n) {
int i, j, ind1, ind2;
double power, denom;
power = 10.0 / M_PI;
denom = sqrt(M_PI);
#pragma omp parallel for
for (i = 0; i < n; i++) {
for (j = i; j < n; j++) {
ind1 = i*n + j;
ind2 = j*n + i;
out[ind1] = pow(A[ind1], power) / denom;
out[ind2] = out[ind1];
}
}
Run Code Online (Sandbox Code Playgroud)
(A是方形双矩阵,out具有相同的形状,n是行/列的数量)因此,点是更新一些对称距离矩阵 - ind2是ind1的转置索引.
我用它编译它gcc -shared -fopenmp -o gaussian.so …
来自python 线程文档
在 CPython 中,由于全局解释器锁,一次只有一个线程可以执行 Python 代码(尽管某些面向性能的库可能会克服这一限制)。如果您希望您的应用程序更好地利用多核机器的计算资源,建议您使用多处理。然而,如果您想同时运行多个 I/O 密集型任务,线程仍然是一个合适的模型。
现在我有一个像这样的线程工作者
def worker(queue):
queue_full = True
while queue_full:
try:
url = queue.get(False)
w = Wappalyzer(url)
w.analyze()
queue.task_done()
except Queue.Empty:
queue_full = False
Run Code Online (Sandbox Code Playgroud)
这里w.analyze()做两件事
requests使用库抓取 urlpyv8使用javascript 库分析抓取的 html据我所知,1是 I/O 限制,2也是 CPU 限制。
这是否意味着,申请了GIL 2,我的程序将无法正常运行?
由于存在GIL,是否有可能在python中具有真正的并行性?据我所知,每个线程在执行之前获取GIL而其他线程一直等到GIL被释放.为什么GIL如果是这样一个瓶颈
有没有一种方法来分析python进程对GIL的使用?基本上,我想找出持有GIL的时间百分比。该进程是单线程的。
我的动机是我有一些用Cython编写的代码,使用nogil。理想情况下,我想在多线程进程中运行它,但是为了知道这是否可能是一个好主意,我需要知道GIL是否有大量时间空闲。
我从8年前就发现了这个相关问题。唯一的答案是“否”。希望此后一切都变了。
我有一个用 Kivy 编写的 Python 应用程序,它使用 C++ 程序进行高速计算,然后返回一个值,我的 Python 应用程序使用该值。
C++ 程序包装在 PyBind11 中并导入到应用程序中,然后从 Python 调用。
我的问题是,当执行 C++ 程序时,我的应用程序会停止一小会儿,但我仍然希望事情在后台进行。
我天真地认为这可以通过线程化 C++ 调用来解决,但转念一想,我认为问题出在 GIL 上。我必须解锁 GIL,如何才能实现这一目标?
根据我所读到的内容(例如此处),我了解 I/O 操作释放了 GIL。因此,如果我必须读取本地文件系统上的大量文件,我的理解是线程执行应该加快速度。
\n为了测试这个 - 我有一个文件夹(input ),其中包含大约 100k 个文件 - 每个文件只有一行,其中包含一个随机整数。我有两个函数 - 一个“顺序”和一个“并发”,只需添加所有数字
import glob\nimport concurrent.futures\nALL_FILES = glob.glob(\'./input/*.txt\')\n \ndef extract_num_from_file(fname):\n #time.sleep(0.1)\n with open(fname, \'r\') as f:\n file_contents = int(f.read().strip())\n return file_contents\n\ndef seq_sum_map_based():\n return sum(map(extract_num_from_file, ALL_FILES)) \n\ndef conc_sum_map_based():\n with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:\n return sum(executor.map(extract_num_from_file, ALL_FILES))\nRun Code Online (Sandbox Code Playgroud)\n虽然这两个函数给出了相同的结果 - “并发”版本大约慢 3-4 倍。
\nIn [2]: %timeit ss.seq_sum_map_based() \n3.77 s \xc3\x82\xc2\xb1 50.2 ms per loop (mean \xc3\x82\xc2\xb1 std. dev. of 7 runs, 1 loop each)\n\nIn [3]: %timeit …Run Code Online (Sandbox Code Playgroud)