1 开启线程的2中方式
开启线程和开启进程的方法基本是一样的,如下
from threading import Thread
import time
def task1(name):
print("%s 开始执行" % name)
time.sleep(3)
print("%s 执行完毕" % name)
if __name__ == '__main__':
thre=Thread(target=task1, args=("线程1",))
thre.start()
from threading import Thread
import time
class MyThread(Thread):
def __init__(self,name):
super().__init__()
self.name = name
def run(self):
print("%s is runing" % self.name)
time.sleep(3)
print("%s is done" % self.name)
if __name__ == "__main__":
t = MyThread("线程1")
t.start()
2 创建线程与创建子进程的区别
from threading import Thread
from multiprocessing import Process
import time,os
t_num = 10
p_num = 10
def thread_task():
global t_num
t_num -= 1
print("thread_task pid:",os.getpid())
def process_task():
global p_num
p_num -= 1
print("process_task pid:",os.getpid())
if __name__ == '__main__':
for i in range(5):
t = Thread(target=thread_task())
t.start()
t.join()
print("t_num = ",t_num)
for i in range(5):
p = Process(target=process_task)
p.start()
p.join()
print("p_num = ",p_num)
print("main pid:",os.getpid())
执行结果
thread_task pid: 7580
thread_task pid: 7580
thread_task pid: 7580
thread_task pid: 7580
thread_task pid: 7580
t_num = 5
process_task pid: 7288
process_task pid: 4740
process_task pid: 3276
process_task pid: 5492
process_task pid: 6956
p_num = 10
main pid: 7500
通过上面这个例子,我们可以看出来,每创建一个子进程的时候,都需要重新申请一块内存空间地址,并且他们都是相互隔离的。每个进程都有各自的pid
而创建线程时,他们共享所在进程的内存空间地址。每个线程的pid与创建他们的进程的pid都是一样的
主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束,
主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。
3 线程的相关方法
# Thread实例对象的方法
# isAlive(): 返回线程是否活动的。
# getName(): 返回线程名。
# setName(): 设置线程名。
# threading模块提供的一些方法:
# threading.currentThread(): 返回当前的线程变量。
# threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
# threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。