Python 开启线程的2中方式,线程VS进程(守护线程、互斥锁)

时间:2023-03-09 22:19:36
Python 开启线程的2中方式,线程VS进程(守护线程、互斥锁)

知识点一:

进程:资源单位
线程:才是CPU的执行单位

进程的运行:
开一个进程就意味着开一个内存空间,存数据用,产生的数据往里面丢
线程的运行:
代码的运行过程就相当于运行了一个线程

辅助理解:一座工厂(操作系统)->没造一个车间(启动一个进程)->每个车间的流水线(线程)

知识点二:开启线程的2种方式

from threading import  Thread
#方式一:(引用系统中thread类)
def task(name):
print('%s is running')
print('%s is done') if __name__ == '__main__':
p=Thread(target=task,args=('子线程',))
p.start() #方式二:(自定义类)
class Mythread(Thread):
def run(self):
print('%s is running'%self.name)
print('%s is done'%self.name) if __name__ == '__main__':
p=Mythread()
p.start()

知识点三:线程VS进程

第一点:
1.多个进程内存空间彼此隔离
2.同一进程下的线程共享该进程内的数据 第二点:
线程的速度快与进程(因为不需要造名称空间,不需要复制父类的代码)
from threading import Thread
# from multiprocessing import Process
import time
x=100
def task(name):
global x
x=50
print('%s is running'%name)
time.sleep(3)
print('%s is done'%name) if __name__ == '__main__':
# p1=Thread(target=task,args=('子线程1',))
# p1=Process(target=task,args=('子线程1',))
# p1.start() # p.daemon=True #验证二:将p设置成守护进程,它会等到除了守护进程p之外的另外2个进程(p和主进程print('主'))都结束的时候才死掉 # p=Thread(target=task,args=('子线程',)) #验证三:线程的速度要远快于进程
# p=Process(target=task,args=('子线程',)) #使用进程
# p.start() #会先打印print=('主') p=Thread(target=task,args=('子线程',)) #使用线程
p.start() #会先打印:子线程 is running #验证一:同一进程下的线程共享该进程类的数据
# print(x) #在主线程里面去调用x 发现x被子线程已经重新修改并复制,所有结果就是x=50 print('主')

知识点四:

知识点四:守护线程
守护线程是等待内部所有线程都运行完毕后结束(因为线程是由进程控制的,
如果和进程一样只是随着主线程结束而结束那么其他线程就也会结束掉)

几个线程的属性:
1.current_thread():current_thread().name可以拿到线程的名字,类似于进程中的self.name命令
2.current_thread().setName 可以更改线程的名字

知识点五:互斥锁实例

线程互斥锁与进程互斥锁的区别,只要在一个进程里线程可以共享进程里面的一块儿数据

#加锁循环对一个共享的数值去减1(主要的作用在于对于共享部分数据,一定要保证用户是逐一串行进来修改值的)
from threading import Thread,Lock
import time mutex=Lock() #线程锁:1.大家都能共享到(所以放这个位置)2.加锁让大家逐一去排队运行,运行完一个,x就减1
x=100 def task():
global x
mutex.acquire()
temp=x #如果不加锁,线程1=100,线程2=100,。。
time.sleep(0.1) #如果不加锁,输出会是100,因为等0.1秒的时候,所有的线程都已经是100了
x=temp-1
mutex.release() if __name__ == '__main__':
start=time.time()
t_l=[] #里面放的是thread1-thread100
for i in range(100):
t=Thread(target=task)
t_l.append(t)
t.start() #线程造出来的时间会非常快
for t in t_l:
t.join() #等待每个线程结束后运行下一步 print('主',x) #这一步肯定是所有的线程都运行完了
print(time.time()-start)

知识点六:死锁现象与解决死锁方案

from threading import Thread,Lock,RLock
import time # mutexA=Lock() #死锁现象就是会存在当放当f1、f2拿着互相的锁,都卡在那里互等对方解锁的现象,导致程序就一直卡在那里
# mutexB=Lock()
mutexA=mutexB=RLock() #改变死锁就是导入递归锁:递归锁的功能就是可以连续的acquire+1+1...加锁,碰到release-1-1...就会自动解锁
class MyThread(Thread):
def run(self):
self.f1()
self.f2() def f1(self):
mutexA.acquire()
print('%s 拿到了A锁' %self.name) mutexB.acquire()
print('%s 拿到了B锁' %self.name)
mutexB.release() mutexA.release() def f2(self):
mutexB.acquire()
print('%s 拿到了B锁' %self.name)
time.sleep(0.1) mutexA.acquire()
print('%s 拿到了A锁' %self.name)
mutexA.release() mutexB.release() if __name__ == '__main__':
for i in range(10):
t=MyThread()
t.start() # t1=MyThread()
# t1.start()
#
# t2=MyThread()
# t2.start()
#
# t3=MyThread()
# t3.start()
print('主')

知识点七:信号量

# from multiprocessing import Semaphore
#信号量:是控制同一时刻并发执行的任务数 sm=Semaphore(5) ,后面的数字就是信号量
#最多同时可以接收5个人,如果出来1个就解锁一个...最多解锁5个
from threading import Thread,Semaphore,current_thread
import time,random sm=Semaphore(5) #代表信号量为5,一次性接收5个值 def go_wc():
sm.acquire()
print('%s 上厕所ing' %current_thread().getName())
time.sleep(random.randint(1,3))
sm.release() if __name__ == '__main__':
for i in range(23):
t=Thread(target=go_wc)
t.start()