Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/302.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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多线程 请考虑此代码: import threading def printer(): for i in range(2): with lock: print ['foo', 'bar', 'baz'] def main(): global lock lock = threading.Lock() threads = [threading.Thread(target=printer) for x in xrange(2)] for t in threads: t.start() t.join() main()_Python_Multithreading - Fatal编程技术网

试图理解python多线程 请考虑此代码: import threading def printer(): for i in range(2): with lock: print ['foo', 'bar', 'baz'] def main(): global lock lock = threading.Lock() threads = [threading.Thread(target=printer) for x in xrange(2)] for t in threads: t.start() t.join() main()

试图理解python多线程 请考虑此代码: import threading def printer(): for i in range(2): with lock: print ['foo', 'bar', 'baz'] def main(): global lock lock = threading.Lock() threads = [threading.Thread(target=printer) for x in xrange(2)] for t in threads: t.start() t.join() main(),python,multithreading,Python,Multithreading,我可以理解这段代码,而且很清楚:我们创建两个线程,然后按顺序运行它们——我们只在第一个线程完成时运行第二个线程。好的,现在考虑另一个变型: import threading def printer(): for i in range(2): with lock: print ['foo', 'bar', 'baz'] def main(): global lock lock = threading.Lock() thre

我可以理解这段代码,而且很清楚:我们创建两个线程,然后按顺序运行它们——我们只在第一个线程完成时运行第二个线程。好的,现在考虑另一个变型:

import threading

def printer():
    for i in range(2):
        with lock:
            print ['foo', 'bar', 'baz']

def main():
    global lock
    lock = threading.Lock()
    threads = [threading.Thread(target=printer) for x in xrange(2)]
    for t in threads:
        t.start()
    for t in threads:
        t.join()

main()

这里发生了什么?好的,我们并行运行它们,但是在第二个变体中让主线程等待子线程的目的是什么?它如何影响输出?

在第二个变体中,执行顺序的定义要少得多。 每次通过回路输入打印机时都会释放锁。在这两种变体中,一个线程中有两个线程和两个循环。 在第一个变体中,因为一次只运行一个线程,所以您知道总的顺序。 在第二种变体中,每次释放锁时,运行的线程可能会发生变化。 所以你可能会

  • 线程1循环1
  • 线程1循环2
  • 线程2循环1
  • 线程2循环2
或许 *线程2循环1 *线程1循环1 *线程1循环2 *线程2循环2

唯一的限制是给定线程中的loop1在该线程中的loop2之前运行,并且两个print语句组合在一起,因为这两个语句都持有锁


在这种特殊情况下,我不确定第二个变量中对
t.join()
的调用是否有明显的效果。它保证主线程将是最后一个结束的线程,但我不确定在这段代码中您是否可以以任何方式观察到这一点。在更复杂的代码中,连接线程可能很重要,因此清理操作只能在所有线程终止后执行。如果您有守护进程线程,这一点也非常重要,因为当所有非守护进程线程终止时,整个程序将终止。

要更好地理解python中的多线程,您需要首先了解
主线程和
子线程之间的关系

main
线程是程序的入口,它是在运行脚本时由系统创建的。例如,在脚本中,
main
函数在
main
线程中运行

子线程
是在实例化
线程
类时由
主线程
创建的

最重要的是主线程如何控制子线程。基本上,
Thread
的实例是
main
线程知道并控制该子线程的所有内容。创建子线程时,该子线程不会立即运行,直到主线程在此线程实例上调用
start
函数。在启动子线程之后,您可以假设
main
线程和
child
线程现在并行运行

但是更重要的一点是
main
线程如何知道
child
线程的任务已经完成。虽然
main
线程不知道
子线程如何完成任务,但它确实知道
子线程的运行状态<代码>线程。是否处于活动状态
可以通过
main
线程检查线程的状态。在实践中,
Thread.join
函数总是用来告诉
main
线程等待
子线程完成。此函数将阻止
main
线程

好的,让我们检查一下您混淆的两个脚本。对于第一个脚本:

for t in threads:
    t.start()
    t.join()
循环中的
子线程是
start
ed,然后是
join
ed。请注意,
start
不会阻止
main
线程,而
join
将阻止
main
线程,直到该
子线程完成。因此,它们是按顺序运行的

而对于第二个脚本:

for t in threads:
    t.start()
for t in threads:
    t.join()
所有
子线程都在第一个循环中启动。由于
Thread.start
函数不会阻止
主线程
线程,因此所有
子线程在第一个循环后并行运行。在第二个循环中,
main
线程将逐个等待每个
子线程的任务完成

现在我认为您应该注意到这两个脚本之间的区别:在第一个脚本中,
子线程
线程逐个运行,而在第二个脚本中,它们同时运行

python线程还有其他有用的主题:

(1) 如何处理键盘中断异常,例如,当我想通过
Ctrl-C
终止程序时?只有
main
线程将接收异常,您必须处理
子线程的终止

(2) 多线程与多处理。虽然我们说线程是并行的,但它并不是CPU级别的真正并行。因此,如果您的应用程序是CPU密集型的,请尝试多处理,如果您的应用程序是I/O密集型的,多线程可能就足够了

顺便说一下,请通读python线程部分的文档,并尝试一些代码,这可能有助于您理解它


希望这会有帮助。谢谢

它的目标是并行运行所有线程,以便同时完成多个作业。尽管Iirc,如果使用CPython实现运行,GIL将阻止它按预期运行。您可能需要澄清您的问题,因为这里不清楚您到底在问什么。调用
thread.join
将等待线程完成执行。因此,第二种情况将启动两个线程运行,然后等待第一个线程完成,然后等待第二个线程完成。实际上,两个线程都将并行运行,哪一个先完成并不重要——主线程将有效地等待两个线程完成(先等待一个线程,然后等待另一个线程)