让多个线程执行一个命令
Make multiple threads exec a single command
我实际上正在编写一个创建虚拟文件的小脚本,用于填充磁盘(一般是 USB 密钥),以确保安全。
实际上,我使用线程模块,即使我知道如何使用它,我仍然在为一些事情而苦苦挣扎。
这是介绍我的问题的一些代码。
import sys
if sys.version_info[0] >= 3: # Check Python's version, and dismiss Python 3
raise Exception('You must use Python 2 to launch this program')
from threading import Thread
index, running = 0, True
def main():
multiThreading()
def multiThreading():
thread1 = Thread(target=fill) # Both threads targets fill()
thread1.daemon = True
thread1.start()
thread2 = Thread(target=fill)
thread2.daemon = True
thread2.start()
while running: # Without this infinite loop, the program exits while the threads are still on, which is not really a problem in this bit of code,
# as they finish their tasks, but it is one in the original script. Anyway.
if running is False:
return None
def fill(): # this function normally fills a chosen drive with data
global index
global running
while running:
index += 1
print index
if index >= 10:
running = False
# The index is used AFTER index += 1 is executed, which causes a problem
if __name__ == '__main__':
main()
print 'End'
哪个returns
12
34
56
78
910
End
>>>
事实上,我想让它打印出来
1
2
3
...
10
End
>>>
但是两个线程都通过索引,它加 2 而不是 1(2 因为当然有两个线程)
我试过看门狗,其他功能,但结果是一样的。
而且,one-time 看门狗也不是解决方案,因为我想根据需要多次循环。
预测题:为什么要用multi-threads?因为它使文件创建速度更快。
你有解决办法吗?非常感谢阅读!
PS: 请原谅我的一些英语错误,不是我的母语:p ; double-PS: 如果你对标题有更好的想法,我的耳朵都打开了
这是因为当多个线程写入流(stdout 或文件)时,它们的输出几乎肯定会混合并产生不可读的结果。你得到至少部分有序的输出主要是因为 python 有 GIL。 (顺便说一句,我得到不同的输出。)在一般情况下,当未指定语言时,没有什么可以阻止 OS 以以下方式调度线程执行:
index += 1 # Thread 1
index += 1 # Thread 2
print index # Thread 2
index += 1 # Thread 2 (next iteration)
print index # Thread 1
所以一般来说,当你写*到共享变量时,你需要用互斥量、信号量或其他同步原语来保护那部分代码,以确保线程可以执行整个临界区 不被打扰:
from threading import Thread, Lock
index_operations_lock = Lock()
def mutlithreading():
# all the stuff you already have
thread1.join()
thread2.join()
def fill():
global index
global running
while running:
with index_operations_lock:
if index >= 10:
running = False
return
index += 1
print index
保护您的竞争资源。另请注意,此方法不指定线程执行顺序。如果您需要从线程一然后从线程二写入,您将需要两个锁或实现生产者-消费者模式(即让两个线程写入队列,让第三个线程从队列中读取并写入文件/标准输出)。
* - 在 python 中,赋值 a = b
也是写入,因为这会增加 b
.
引用的对象中的引用计数器
我实际上正在编写一个创建虚拟文件的小脚本,用于填充磁盘(一般是 USB 密钥),以确保安全。
实际上,我使用线程模块,即使我知道如何使用它,我仍然在为一些事情而苦苦挣扎。
这是介绍我的问题的一些代码。
import sys
if sys.version_info[0] >= 3: # Check Python's version, and dismiss Python 3
raise Exception('You must use Python 2 to launch this program')
from threading import Thread
index, running = 0, True
def main():
multiThreading()
def multiThreading():
thread1 = Thread(target=fill) # Both threads targets fill()
thread1.daemon = True
thread1.start()
thread2 = Thread(target=fill)
thread2.daemon = True
thread2.start()
while running: # Without this infinite loop, the program exits while the threads are still on, which is not really a problem in this bit of code,
# as they finish their tasks, but it is one in the original script. Anyway.
if running is False:
return None
def fill(): # this function normally fills a chosen drive with data
global index
global running
while running:
index += 1
print index
if index >= 10:
running = False
# The index is used AFTER index += 1 is executed, which causes a problem
if __name__ == '__main__':
main()
print 'End'
哪个returns
12
34
56
78
910
End
>>>
事实上,我想让它打印出来
1
2
3
...
10
End
>>>
但是两个线程都通过索引,它加 2 而不是 1(2 因为当然有两个线程)
我试过看门狗,其他功能,但结果是一样的。 而且,one-time 看门狗也不是解决方案,因为我想根据需要多次循环。
预测题:为什么要用multi-threads?因为它使文件创建速度更快。
你有解决办法吗?非常感谢阅读!
PS: 请原谅我的一些英语错误,不是我的母语:p ; double-PS: 如果你对标题有更好的想法,我的耳朵都打开了
这是因为当多个线程写入流(stdout 或文件)时,它们的输出几乎肯定会混合并产生不可读的结果。你得到至少部分有序的输出主要是因为 python 有 GIL。 (顺便说一句,我得到不同的输出。)在一般情况下,当未指定语言时,没有什么可以阻止 OS 以以下方式调度线程执行:
index += 1 # Thread 1
index += 1 # Thread 2
print index # Thread 2
index += 1 # Thread 2 (next iteration)
print index # Thread 1
所以一般来说,当你写*到共享变量时,你需要用互斥量、信号量或其他同步原语来保护那部分代码,以确保线程可以执行整个临界区 不被打扰:
from threading import Thread, Lock
index_operations_lock = Lock()
def mutlithreading():
# all the stuff you already have
thread1.join()
thread2.join()
def fill():
global index
global running
while running:
with index_operations_lock:
if index >= 10:
running = False
return
index += 1
print index
保护您的竞争资源。另请注意,此方法不指定线程执行顺序。如果您需要从线程一然后从线程二写入,您将需要两个锁或实现生产者-消费者模式(即让两个线程写入队列,让第三个线程从队列中读取并写入文件/标准输出)。
* - 在 python 中,赋值 a = b
也是写入,因为这会增加 b
.