python_多线程中的一点问题

本文详细介绍了Python中线程的控制方法,包括如何使用join()和setDaemon()方法来调整主线程与子线程的执行顺序。通过实例演示了不同设置下线程的行为差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文核心:

python中所有的子线程是否是守护进程都继承自主线程,因为主线程默认是非守护进程,因此,所有的由该主线程创建的子线程都不是守护进程。

当所有的非守护进程结束的时候,python程序也就结束了

本文提纲:

  1. 如果什么都不设置,默认是:父线程和子线程先后开始,当父线程、子线程都完成时,程序退出。
  2. 如果在子线程start之前,调用了setDeamon(True)方法:父子线程先后开始当父线程结束时,不论子线程是否完成,程序均退出。
  3. 如果子线程对象调用了join()方法,那么,程序运行到该处时,父线程在此处等待子线程的完成,当子线程完成时,父线程继续执行。直至父线程完成,程序退出。


主要是涉及到 join()、setDeamon()的相关内容。本文中,通过在子线程中设置sleep(10),来控制子线程和父线程完成的先后顺序,进行测试。因此,本文涉及到的代码大多数是相同的,只需要关注每段代码中的join()、setDeamon(True)、sleep(10)即可。


一、如果什么都不设置,默认是:父线程和子线程先后开始,当父线程、子线程都完成时,程序退出。


1、下面是父线程先结束的例子,可以看出,父线程已经结束,而子线程由于sleep(10),而后结束,但程序是等父子线程全部完成后,才退出。

import threading
from time import ctime,sleep



class MyThread(threading.Thread):
    def __init__(self, id):
        threading.Thread.__init__(self)
        self.id = id

    def run(self):
        x = 0
        print "son thread stard...%s"  %ctime()
        sleep(10)
        print self.id
        print "son thread end..... %s" %ctime()


if __name__ == "__main__":
    print "main is start %s " %ctime()
    t1 = MyThread(999)
    t1.start()
    for i in range(3):
        print i
    print "main thread end......."
运行结果如下:
main is start Wed Feb 07 13:02:44 2018 
son thread stard...Wed Feb 07 13:02:44 2018
0
1
2
main thread end.......
999
son thread end..... Wed Feb 07 13:02:54 2018


2、下面是子线程先结束的例子:可以看出,子线程先结束,而后父线程结束。(将1中的sleep(10)注释掉)

import threading
from time import ctime,sleep

class MyThread(threading.Thread):
    def __init__(self, id):
        threading.Thread.__init__(self)
        self.id = id

    def run(self):
        x = 0
        print "son thread stard...%s"  %ctime()
        # sleep(10)
        print self.id
        print "son thread end..... %s" %ctime()


if __name__ == "__main__":
    print "main is start %s " %ctime()
    t1 = MyThread(999)
    t1.start()
    for i in range(3):
        print i
    print "main thread end......."
运行结果如下:
main is start Wed Feb 07 13:09:04 2018 
son thread stard...Wed Feb 07 13:09:04 2018
999
0
son thread end..... Wed Feb 07 13:09:04 2018
1
2
main thread end.......

解释:由于父线程默认为非守护线程,子线程继承父线程,同样为非守护线程。python中,当所有的非守护线程都执行完时,程序结束。于是在上述情况中,只有当父子线程都结束,程序才退出。


二、如果在子线程start之前,调用了setDeamon(True)方法:父子线程先后开始,当父线程结束时,不论子线程是否完成,程序均退出。

1、下面是子线程先结束的例子:可以看出,子线程先结束,结束后,父线程随后结束。

import threading
from time import ctime,sleep

class MyThread(threading.Thread):
    def __init__(self, id):
        threading.Thread.__init__(self)
        self.id = id

    def run(self):
        x = 0
        print "son thread stard...%s"  %ctime()
        # sleep(10)
        print self.id
        print "son thread end..... %s" %ctime()


if __name__ == "__main__":
    print "main is start %s " %ctime()
    t1 = MyThread(999)
    t1.setDaemon(True)
    t1.start()
    for i in range(3):
        print i
    print "main thread end......."
运行结果如下:
main is start Wed Feb 07 13:19:13 2018 
son thread stard...Wed Feb 07 13:19:13 2018
999
0
son thread end..... Wed Feb 07 13:19:13 2018
1
2
main thread end.......

2、下面是父线程先结束的例子:可以看出,在这个例子中,父线程结束,子线程还没有结束,程序就退出。

import threading
from time import ctime,sleep

class MyThread(threading.Thread):
    def __init__(self, id):
        threading.Thread.__init__(self)
        self.id = id

    def run(self):
        x = 0
        print "son thread stard...%s"  %ctime()
        sleep(10)
        print self.id
        print "son thread end..... %s" %ctime()


if __name__ == "__main__":
    print "main is start %s " %ctime()
    t1 = MyThread(999)
    t1.setDaemon(True)
    t1.start()
    for i in range(3):
        print i
    print "main thread end......."
运行结果为:
main is start Wed Feb 07 13:25:20 2018 
son thread stard...Wed Feb 07 13:25:20 2018
0
1
2
main thread end.......

解释:由于父线程默认为非守护线程,子线在上述两个例子中被设置为守护线程。python中,当所有的非守护线程都执行完时,程序结束。于是在上述情况中,当作为非守护线程的父线程运行完时,该程序退出。


三、如果子线程对象调用了join()方法,那么,程序运行到该处时,父线程在此处等待子线程的完成,当子线程完成时,父线程继续执行。直至父线程完成,程序退出。

1、下面的代码:子线程用时比父线程要多,但父线程等子线程运行完后,才继续运行。

import threading
from time import ctime,sleep



class MyThread(threading.Thread):
    def __init__(self, id):
        threading.Thread.__init__(self)
        self.id = id

    def run(self):
        x = 0
        print "son thread stard...%s"  %ctime()
        sleep(10)
        print self.id
        print "son thread end..... %s" %ctime()


if __name__ == "__main__":
    print "main is start %s " %ctime()
    for i in range(3):
        print i
    t1 = MyThread(999)

    t1.start()
    t1.join()
    for x in range(3,5):
        print x
    print "main thread end......."

运行结果:
main is start Wed Feb 07 13:42:50 2018 
0
1
2
son thread stard...Wed Feb 07 13:42:50 2018
999
son thread end..... Wed Feb 07 13:42:50 2018
3
4
main thread end.......

解释:当子线程调用了join()方法时,父线程在join()处等待子线程执行完毕,才继续执行。等父线程也执行完,程序退出(由于父子线程均为非守护线程,因此,当父子全完时,程序才退出)


### 回答1: 很抱歉,我之前回答的还是这个问题。以下是一个稍微复杂一点Python 多线程实例,可以用来计算一个矩阵的乘积: ```python import threading import numpy as np # 定义矩阵的大小 MATRIX_SIZE = 1000 # 初始化两个随机矩阵 matrix_a = np.random.rand(MATRIX_SIZE, MATRIX_SIZE) matrix_b = np.random.rand(MATRIX_SIZE, MATRIX_SIZE) # 初始化结果矩阵 result_matrix = np.zeros((MATRIX_SIZE, MATRIX_SIZE)) # 定义一个函数,用来计算矩阵的乘积 def multiply(start, end): for i in range(start, end): for j in range(MATRIX_SIZE): for k in range(MATRIX_SIZE): result_matrix[i][j] += matrix_a[i][k] * matrix_b[k][j] # 定义线程数量 NUM_THREADS = 4 # 计算每个线程需要计算的行数 rows_per_thread = MATRIX_SIZE // NUM_THREADS # 创建线程列表 threads = [] # 启动线程 for i in range(NUM_THREADS): start = i * rows_per_thread end = (i + 1) * rows_per_thread t = threading.Thread(target=multiply, args=(start, end)) threads.append(t) t.start() # 等待所有线程结束 for t in threads: t.join() # 检查结果是否正确 expected_result = np.dot(matrix_a, matrix_b) assert np.array_equal(result_matrix, expected_result) # 输出 Done 表示程序执行完毕 print("Done") ``` 这个例子首先初始化两个随机矩阵,然后定义一个函数 multiply,用来计算这两个矩阵的乘积。然后,它将矩阵分成若干个部分,每个部分分配给一个线程来计算。最后,它等待所有线程结束,检查结果是否正确,并输出 Done 表示程序执行完毕。 希望这个例子能够帮助您更好地理解 Python 多线程的使用方法。 ### 回答2: Python多线程实例是指在Python编程语言中使用多线程进行并发编程的实例。在Python中,可以使用内置的threading模块来创建和管理多线程。 通过创建多线程,可以在程序中同时执行多个任务。这对于需要同时处理多个任务的情况非常有用。例如,在下载大文件时,可以使用多线程同时下载多个文件,加快下载速度。此外,多线程还可以用于处理网络请求、图像处理、数据处理等耗时操作,提高程序的运行效率。 使用Python多线程的主要步骤如下: 1. 导入threading模块。 ``` import threading ``` 2. 创建一个线程对象,可以通过继承threading.Thread类或使用threading.Thread()函数创建。 ``` class MyThread(threading.Thread): def __init__(self, name): super().__init__() self.name = name def run(self): # 线程执行的代码 print("Hello, " + self.name) thread1 = MyThread("Thread 1") thread2 = threading.Thread(target=func, args=("Thread 2",)) ``` 3. 启动线程。 ``` thread1.start() thread2.start() ``` 4. 等待线程结束。 ``` thread1.join() thread2.join() ``` 以上代码演示了两种创建多线程的方法:1)继承threading.Thread类,重写run方法;2)使用函数作为线程执行内容。线程的启动调用start()方法,等待线程结束使用join()方法。 需要注意的是,Python多线程的并发程度受到全局解释器锁(GIL)的限制,因此对于计算密集型的任务,多线程不能发挥出多核的优势。如果需要发挥多核性能,可以考虑使用多进程编程。 总之,Python多线程实例能够提高程序的并发处理能力,适用于需要同时处理多个任务的场景。通过合理设计线程的数量和任务分配,可以提高程序的性能和效率。 ### 回答3: Python多线程实例是指通过使用多线程的技术来提高Python程序的运行效率和性能。在Python中,我们可以使用threading模块来实现多线程多线程技术可以同时执行多个任务,提高程序的运行速度。在Python中,我们可以通过创建Thread对象并调用start()方法来启动一个线程。下面是一个简单的例子: import threading def print_numbers(): for i in range(1, 11): print(i) def print_letters(): for letter in ['A', 'B', 'C', 'D', 'E']: print(letter) # 创建两个线程 t1 = threading.Thread(target=print_numbers) t2 = threading.Thread(target=print_letters) # 启动两个线程 t1.start() t2.start() # 等待两个线程结束 t1.join() t2.join() # 主线程继续执行 print("主线程结束") 以上代码中,我们创建了两个线程,分别执行print_numbers()和print_letters()函数。通过调用start()方法启动线程,并通过join()方法等待两个线程执行完毕。最后,主线程继续执行并打印出一段文字。 需要注意的是,多线程并不一定能提高程序的运行速度,因为在Python中,全局解释器锁(Global Interpreter Lock,GIL)会限制同一时间只能有一个线程执行Python字节码。因此,在CPU密集型任务中,多线程不能真正实现并行计算。但是,在IO密集型任务中,多线程能够提高程序的运行效率。 总结起来,Python多线程实例可以通过使用threading模块来实现。多线程能够提高IO密集型任务的运行效率,但在CPU密集型任务中并不能真正实现并行计算。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值