学习日记28

今日内容

线程的概念

进程是操作系统调度的最小单位
一个进程至少有一个线程
一个进程中可以开多个线程
线程是cpu调度的最小单位
真正干活的是线程

如何开启线程

from multiprocessing import Process
from threading import Thread

def task():
   print('1')
   
if __name__ == '__main__':
   t = Thread(target=task , args=())
   t.start()

GIL锁

python在设计之初就考虑到要在主循环中,同时只有一个线程在执行
虽然python解释器可以运行多个线程,但是在任意时刻只有一个线程在解释器中执行

GIL锁是在python解释器中的,只有在cpython中有,pypy解释器是没有的
起一个垃圾回收线程,一个是正常执行的线程
设置了一把锁(GIL锁),一个线程想要执行,必须拿到这把锁
同一时刻,开启一个进程,一个进程中可以有多个线程,只能有一个线程在执行
如果是计算密集型:要开进程
如果是io密集型:要开线程

进程和线程的效率比较

def task():
   time.sleep(1)
   print('主线程')

if __name__ == '__main__':
   ctime = time.time()
   t = Process(target=task , args=())
   t.start()
   t.join()
   print('主线程')
   print(time.time() - ctime)
   
# 进程结果1.1050267219543457

def task():
   time.sleep(1)
   print('主线程')

if __name__ == '__main__':
   ctime = time.time()
   t = Thread(target=task , args=())
   t.start()
   t.join()
   print('主线程')
   print(time.time() - ctime)
   
# 线程结果1.0038325786590576

线程之间的数据共享问题

线程之间的数据是共享的
进程之间的数据是隔离的

threading模块

t.is_alve() # 判断线程是否存活
t.setName() # 线程名
threading.currentThread() # 当前线程的变量
threading.emumerate() # 以列表的形式显示正在运行的线程
threading.activeCount() # 返回现在运行的线程数量
t = Thread(target=task , args=()) # 开启守护线程,主线程结束,子进程跟着结束

def task():
   time.sleep(1)
   print('主线程')

if __name__ == '__main__':
   t = Thread(target=task , args=())
   t.start()
   print('主线程')

互斥锁

# 并发编程的弊端,数据安全问题
from threading import Thread,Lock
import time
def task(lock):
   lock.acquire()
   global n
   temp = n
   # 并发安全问题
   # n-=1
   time.sleep(1)
   n = temp - 1
   lock.release()
if __name__ == '__main__':
   n = 10
   lock=Lock()
   ll = []
   for i in range(10):
       t = Thread(target=task,args=(lock,) )
       t.start()
       ll.append(t)
   for j in ll:
       j.join()
   print('主线程', n)

信号量

信号量等同于多把锁,允许多个线程更改数据
from threading import Thread,Lock
import time
def task(i,sm):
   sm.acquire() # 上锁
   print('%s开始了'% i)
   time.sleep(1)
   print('%s结束了'% i)
   sm.release() # 解锁

if __name__ == '__main__':
   sm = Semaphore(1) # 实例化
   for i in range(10):
       t = Thread(target=task , args=(i,sm))
       t.start()

Event事件

def girl(event):
   print('恋爱中')
   time.sleep(3)
   print('分手了')
   event.set() # 发出信号


def boy(event, i):
   print('%s等待中' % i)
   event.wait()  # 等待接收信号
   print('%s开始追了' % i)


if __name__ == '__main__':
   event = Event()  # 实例化
   t = Thread(target=girl, args=(event,))
   t.start()
   ll = []
   for i in range(3):
       b_t = Thread(target=boy, args=(event, i))
       b_t.start()
       ll.append(b_t)
   for j in ll:
       j.join

 

posted @ 2021-07-22 14:42  小白白柏柏  阅读(53)  评论(0)    收藏  举报