同步:代码执行完继续执行下一步
异步:同时执行代码,执行完再进行下一步
互斥锁:
当多个线程几乎同时修改某一个共享的数据时,需要进行同步操作,引入互斥锁
当一个线程更改数据的时候,先将它锁定,其他线程不能修改,直到线程操作全部完成,此时会释放资源
互斥锁保证了同一时刻,只有一个线程能对资源进行操作,保证数据的正确性
# from threading import Thread
import threading
import time
g_num = 0
def work1(num):
global g_num
for i in range(num):
#上锁,核心代码上锁
ret=lock.acquire(True)
print(ret)
g_num +=i
lock.release()
print('work1:',g_num)
def work2(num):
global g_num
for i in range(num):
ret=lock.acquire(True)
if ret:
g_num += i
lock.release()
print('work2:',g_num)
if __name__ == '__main__':
lock=threading.Lock()
first_thread=threading.Thread(target=work1,args=(10,))
second_thread=threading.Thread(target=work2,args=(10,))
first_thread.start()
# first_thread.join()
time.sleep(0.9)
second_thread.start()
(该代码中加入一个延时,执行可以结果更加清晰一点)
lock=threading.lock
lock.acquire()锁定
lock.release()释放
死锁:
多个线程互相等待对方的锁,互相占同一资源不放,避免死锁,超时释放。
生产者与消费者模块:
生产者:生产数据
消费者:消费数据
队列:先进先出
栈:先进后出
进程状态:新建态、就绪态、终止态、运行态、阻塞态
多进程之间的资源共享问题
多进程之间不再共享全局变量
进程池队列:
1.import queue
2.from multiprocessing import Manager,Pool
3.form multiprocessing import Queue
pool.apply:apply方法是阻塞的。就是等待当前子进程执行完毕后,在执行下一个进程。
结果:因为apply是阻塞的,所以进入子进程执行后,等待当前子进程执行完毕,在继续执行下一个进程。
pool.apply_asyns:是异步非阻塞的。就是不用等待当前进程执行完毕,随时根据系统调度来进行进程切换。
结果:完全没有等待子进程执行完毕,主进程就已经执行完毕,并退出程序。
进程与线程对比:
1.线程是进程中的一个实例,真正在运行的是线程
2.进程只是资源分配的基本单位,线程是调度的基本单位
3.没有进程就没有线程这个概念
4.不同的进程一起运行,其中一个进程死亡,其他进程不受任何影响
5.在同一个进程内,如果线程消亡,那这个进程就会受到影响,所以从健壮性来说,进程比线程更加稳定
6.线程共享全局变量,进程创建自进程相当于粘贴复制,此时相当于创建了一份副本,不共享全局变量