Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.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_Multithreading_Mutex - Fatal编程技术网

Python中互斥体的正确使用

Python中互斥体的正确使用,python,multithreading,mutex,Python,Multithreading,Mutex,我从python中的多线程开始(或者至少我的脚本可能创建多个线程)。这个算法是互斥的正确用法吗?我还没有测试过这段代码,它甚至可能不会工作。我只希望processData在一个线程(一次一个)中运行,并且主while循环保持运行,即使队列中有线程 from threading import Thread from win32event import CreateMutex mutex = CreateMutex(None, False, "My Crazy Mutex") while(1)

我从python中的多线程开始(或者至少我的脚本可能创建多个线程)。这个算法是互斥的正确用法吗?我还没有测试过这段代码,它甚至可能不会工作。我只希望processData在一个线程(一次一个)中运行,并且主while循环保持运行,即使队列中有线程

from threading import Thread
from win32event import CreateMutex
mutex = CreateMutex(None, False, "My Crazy Mutex")
while(1)
    t = Thread(target=self.processData, args=(some_data,))
    t.start()
    mutex.lock()

def processData(self, data)
    while(1)
        if mutex.test() == False:
            do some stuff
            break

编辑:重新阅读我的代码,我可以看到它是严重错误的。但是,嘿,这就是我在这里寻求帮助的原因。

你必须在某个时候解锁你的互斥锁…

我不知道你为什么使用窗口的互斥锁而不是Python的互斥锁。使用Python方法,这非常简单:

from threading import Thread, Lock

mutex = Lock()

def processData(data):
    mutex.acquire()
    try:
        print('Do some stuff')
    finally:
        mutex.release()

while True:
    t = Thread(target = processData, args = (some_data,))
    t.start()

但是请注意,由于CPython(即)的体系结构,您实际上一次只能运行一个线程——如果其中有许多线程是I/O绑定的,这是可以的,尽管您希望尽可能释放锁,以便I/O绑定的线程不会阻止其他线程运行

对于Python 2.6和更高版本,另一种选择是使用Python的
多处理
包。它镜像了
线程
包,但将创建可以同时运行的全新进程。更新您的示例很简单:

from multiprocessing import Process, Lock

mutex = Lock()

def processData(data):
    with mutex:
        print('Do some stuff')

if __name__ == '__main__':
    while True:
        p = Process(target = processData, args = (some_data,))
        p.start()

这就是我提出的解决方案:

import time
from threading import Thread
from threading import Lock

def myfunc(i, mutex):
    mutex.acquire(1)
    time.sleep(1)
    print "Thread: %d" %i
    mutex.release()


mutex = Lock()
for i in range(0,10):
    t = Thread(target=myfunc, args=(i,mutex))
    t.start()
    print "main loop %d" %i
输出:

main loop 0
main loop 1
main loop 2
main loop 3
main loop 4
main loop 5
main loop 6
main loop 7
main loop 8
main loop 9
Thread: 0
Thread: 1
Thread: 2
Thread: 3
Thread: 4
Thread: 5
Thread: 6
Thread: 7
Thread: 8
Thread: 9
我想从现在开始提高 再多一点

请参阅下面的代码:

from threading import Thread, Lock
import threading
mutex = Lock()


def processData(data, thread_safe):
    if thread_safe:
        mutex.acquire()
    try:
        thread_id = threading.get_ident()
        print('\nProcessing data:', data, "ThreadId:", thread_id)
    finally:
        if thread_safe:
            mutex.release()


counter = 0
max_run = 100
thread_safe = False
while True:
    some_data = counter        
    t = Thread(target=processData, args=(some_data, thread_safe))
    t.start()
    counter = counter + 1
    if counter >= max_run:
        break
在第一次运行时,如果在while循环中设置
thread\u safe=False
,将不使用互斥,线程将在如下打印方法中相互跳过

但是,如果您设置
thread\u safe=True
并运行它,您将看到所有输出都非常好


希望这能有所帮助。

很难弄清楚你想做什么。您需要更详细地解释您的意图。@Marcelo Cantos,对不起,您可能是对的。我希望processData中的代码以新的方式开始。我只希望一个线程一次能够处理数据,并按照数据发送到处理数据的顺序处理数据。我还希望主while循环在其他线程处于队列中时保持循环。@Richard:如果您计划序列化所有处理,为什么要使用线程?简单的循环有什么问题?另外,为什么希望主线程保持循环?它只会消耗CPU,可能会耗尽其他线程。@Marcelo Cantos,这不是我的实际程序。我的实际脚本已达到500多行代码,其中包括数据库条目和电子邮件。我希望主线程只读取一个串行端口,这样在处理接收到的数据之前,缓冲区被填满的可能性就更小了。如果我错了,请纠正我,但我认为这正是使用线程或multiprocessing@Richard:这对于主线程来说是有意义的,但是如果所有其他处理都是顺序的,那么您可以只创建一个其他线程来完成所有其他工作。这可能会出现死锁。如果print语句引发异常,则永远不会释放互斥锁。您需要使用
try/release
with
来确保锁被释放。请看我的答案。另外,没有必要将互斥体作为参数传递给函数。它在全局范围内可用。我尝试了您的代码,但出现以下错误:mutex:SyntaxError:invalid syntax。我想我可以使用try:except:在我的函数中,我使用的是Python2.4
是Python2.5,而多处理是Python2.6。相应地进行了编辑。“如果其中许多是I/O绑定的,这很好”实际上,如果它们是CPU绑定的,也很好,只要这是在对用C编写的库的调用中,而不是在纯Python代码中(例如,如果您在numpy中操作大矩阵)因为在这些调用过程中GIL被解锁。@demented hedgehog:mutex模块已被弃用。使用
线程化
多处理
模块创建互斥锁(答案中已说明)并不是不推荐的做法。特别适合于消息的I/O对齐