线程
进程与线程其实都是虚拟单位,都是用来帮助我们形象的描述某种事物
进程自带一个线程,线程才是真正的执行单位,进程值时在线程运行过程中提供代码运行所需的资源
进程:资源单位 (车间)
1.申请内存空间 耗资源
2.''拷贝代码'' 耗资源
线程:执行单位 (流水线)
一个进程内可以开启多个线程,并且线程与线程之间数据时共享的
threading
Thread 类
开启线程的两种方式
from threading import Thread import time def func(name): print('%s running'%name) time.sleep(3) print('over') # 创建线程对象 开线程不需要在__main__代码内,但是习惯性还是写在__main__内 t = Thread(target=func, args=('waller',)) t.start() # 开启线程 print('主') class MyThread(Thread): def __init__(self, name): super().__init__() self.name = name def run(self): print('%s running' % self.name) time.sleep(3) print('over') t = MyThread('waller') t.start() print('主') # 开线程不需要开启内存空间,所以相当于直接运行线程 ''' waller running 主 over '''
线程对象及其他方法
# isAlive(): 返回线程是否活动的。 # getName(): 返回线程名。 # setName(): 设置线程名。 # active_count(): 当前获取的线程数.
from threading import Thread, current_thread,active_count import os import time def func(name, i): print('%s running'%name) print('子线程current_thread:',current_thread().name) print('子线程getpid:', os.getpid()) time.sleep(i) print('over') t1 = Thread(target=func, args=('waller', 1)) t2 = Thread(target=func, args=('waller', 2)) t1.start() t2.start() # t1.join() # 主线程等到子线程t1运行结束后再运行 print('当前活跃线程数:',active_count()) print('主')
守护线程
无论是进程还是线程,都遵循:守护xxx会等待主xxx运行完毕后被销毁 需要强调的是:运行完毕并非终止运行 #1.对主进程来说,运行完毕指的是主进程代码运行完毕 #2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕
t.daemo = True
主线程必须等待其他非守护线程的结束才能结束
(因为子线程在运行的时候需要使用进程中的资源,而主线程一旦结束资源也就消除了)
详解: #1 主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束, #2 主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。
from threading import Thread, current_thread import time def func(i): print(current_thread().name) time.sleep(i) print('over') t = Thread(target=func, args=(1,)) t.daemon = True t.start() print('主') ''' Thread-1 主 '''
线程间通信
线程间的数据是共享的
from threading import Thread # 线程之间数据时共享的 x = 100 def num(): global x x = 666 t = Thread(target=num) t.start() print(x) # >>> 666
线程互斥锁
多个线程操作同一个数据也会出现数据混乱现象 需要上锁
from threading import Thread, Lock import time x = 5 def num(mutex): global x mutex.acquire() number = x time.sleep(1) x = number - 1 mutex.release() l = [] mutex = Lock() for i in range(5): t = Thread(target=num, args=(mutex,)) t.start() l.append(t) for t in l: t.join() # 主线程等待每个子线程运行结束后再运行 print(x) print(l) # [<Thread(Thread-1, stopped 25852)>, <Thread(Thread-2, stopped 26124)>, # <Thread(Thread-3, stopped 7944)>, <Thread(Thread-4, stopped 17120)>, # <Thread(Thread-5, stopped 19236)>]
例
from threading import Thread from multiprocessing import Process import time def foo(): print(123) time.sleep(1) print("end123") def bar(): print(456) time.sleep(3) print("end456") if __name__ == '__main__': t1=Thread(target=foo) t2=Thread(target=bar) t1.daemon=True t1.start() t2.start() print("main-------") ''' 123 456 main------- end123 end456 '''