Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何强制执行不同的线程_Python - Fatal编程技术网

Python 如何强制执行不同的线程

Python 如何强制执行不同的线程,python,Python,我有一个主线程,它执行一些CPU密集型操作。线程必须为其所有计算保持锁 还有一些其他线程偶尔需要在短时间内使用相同的锁 如果没有其他线程,我如何强制主线程或主线程偶尔允许其他线程执行而不减慢它的速度 周期 lock.release() time.sleep(x) lock.acquire() 对于某些情况,x会将控制传递给另一个线程,但如果没有其他线程,则会减慢主线程的速度 另一方面,如果没有sleep()调用,GIL似乎会在这里产生干扰。由于主线程在执行release()时具有GIL,因此另

我有一个主线程,它执行一些CPU密集型操作。线程必须为其所有计算保持锁

还有一些其他线程偶尔需要在短时间内使用相同的锁

如果没有其他线程,我如何强制主线程或主线程偶尔允许其他线程执行而不减慢它的速度

周期

lock.release()
time.sleep(x)
lock.acquire()
对于某些情况,x会将控制传递给另一个线程,但如果没有其他线程,则会减慢主线程的速度

另一方面,如果没有
sleep()
调用,GIL似乎会在这里产生干扰。由于主线程在执行
release()
时具有GIL,因此另一个线程显然无法立即从
acquire()
返回。因此,主线程继续使用自己的
acquire()
方法,其他线程永远不会获得锁,除非GIL开关恰好与我释放自己的锁的时间一致

这个问题的正确解决方案是什么?有没有办法强制释放GIL?基本上,我需要一些神奇的代码,确保在下面的测试脚本中,第二个线程总是首先获得锁:

import threading
import time

class t1 (threading.Thread):
    def run(self):
    print "Second thread waiting for lock"
    lock.acquire()
    print "Second thread got lock"
    lock.release()

lock = threading.Lock()
lock.acquire()

t = t1()
t.start()
time.sleep(1)

lock.release()
time.sleep(0) # this works very often, but not all the time
lock.acquire()
print "Main thread got lock"
lock.release()

超时为0的调用将短暂释放GIL。

仅释放GIL并不保证其他线程有机会运行

在Unix中,您真正需要的调用是
sched\u yield()
。Python标准库中没有该函数的接口;添加一个带有本机模块的模块是很简单的


usleep(0)
select()
有时用于相同的目的,尽管根据系统调度程序的不同,它们并不总是相同的。Windows,您需要睡眠(0)。将time.sleep(0)用于两者。

time.sleep(0)不起作用。试试我刚才附加在问题上的脚本。大多数情况下,第二个线程首先获得锁,但有时它是主线程。是否在睡眠期间调度另一个线程取决于调度程序。无法保证调度程序会做什么;它可以决定主线程应该继续。一个好的调度程序应该是公平的——也就是说,它应该经常工作,这样就不会有线程完全耗尽,但是严重依赖调度程序的公平性是有风险的。总的来说,两个线程在一个互斥体上不断竞争,而它们必须为执行互斥体而斗争,这是一个糟糕的线程设计。特别要感谢这个有缺陷的网站,当我在上面的评论中试图解决它的格式问题时,首先说我只能每5秒编辑一条评论(毫无意义),然后说“此评论无法再编辑”。欢迎使用PainInAsArbitraryRestrictionOverflow。不幸的是,sched_yield实际给出的结果比时间差。sleep(0)。我使用sched_yield()尝试了上述测试脚本由提供,并且通常主线程会继续运行。好主意,但它不起作用。请尝试将其插入我刚刚发布的示例脚本中。这是因为线程库尚未决定其他线程是否应运行。如果要提高选择其他线程运行的机会,则需要非零时间t、 您可以使用Queue.PriorityQueue()为工作线程提供获取锁所需的所有操作。这样,您可以确保高优先级的小任务在密集CPU操作完成后立即完成。