1.什么是线程
进程其实不是一个执行单位. 进程是一个资源单位
每个进程内自带一个线程. 线程才是cpu上的执行单位
如果把操作系统比喻一座工厂
在工厂中每造出一个车间 -> 启动一个进程
每个车间至少有一条流水线 -> 每个进程至少有一个线程
线程 -> 单指代码的执行过程
进程 -> 资源的申请与销毁的过程
2.进程vs线程
1. 内存共享or隔离
多个进程内存空间彼此隔离
同一进程下的多个线程共享该进程内的数据
2. 创造速度
创建线程的速度要远远快与造进程
3.创建线程的两种方式
from threading import Thread
import time
def task(name):
print('%s is running' % name)
time.sleep(2)
print('done')
if __name__ == '__main__':
t = Thread(target=task, args=('maxs_hu', ))
t.start()
print('主')
"""
maxs_hu is running
主
done
"""
class Mythreading(Thread):
def run(self):
print('%s is running' % self.name)
time.sleep(3)
print('%s is done' % self.name)
if __name__ == '__main__':
t = Mythreading()
t.start()
print('main')
4.线程vs进程代码实现
from threading import Thread
from multiprocessing import Process
def task(name):
print(f'{name} is running')
if __name__ == '__main__':
t = Thread(target=task, args=('子线程', ))
p = Process(target=task, args=('子进程', ))
p.start()
t.start()
print('main')
x = 100
def task():
global x
x = 1
if __name__ == '__main__':
t = Thread(target=task)
t.start()
t.join()
print(x)
import os
def task():
print('pid: %s' % os.getpid())
if __name__ == '__main__':
t = Thread(target=task)
t.start()
print('主线程: %s' % os.getpid())
5.守护线程
from threading import Thread, current_thread
import time
def foo():
print(123)
time.sleep(3)
print("end123")
def bar():
print(456)
time.sleep(1)
print("end456")
t1 = Thread(target=foo)
t2 = Thread(target=bar)
t1.daemon = True
t1.start()
t2.start()
print("main-------")
"""
123
456
main-------
end456
"""
6.守护线程
from threading import Thread, Lock
import time
x = 100
mutex = Lock()
def task():
global x
mutex.acquire()
temp = x
time.sleep(0.1)
x = temp - 1
mutex.release()
if __name__ == '__main__':
t_ls = []
start_time = time.time()
for i in range(100):
t = Thread(target=task)
t_ls.append(t)
t.start()
for t in t_ls:
t.join()
print(x, time.time()-start_time)
7.死锁现象和递归锁
"""
什么是死锁现象:
相当于两个人拿着对方家里的钥匙. 被锁门里面了
互相等着拿对方的锁的现象
怎么解决死锁现象:
递归锁: Rlock原理
给不同的锁赋值obj递归锁对象. 被赋值的锁被acquire多次. 就会在整体标记多次. 只要存在标记. 后面的线程就只能等着
而只有release消除所有的标记次数. 才能开始抢锁. 从而解决死锁现象
递归锁的特点:可以连续的acquire
"""
from threading import Thread, Lock, active_count, RLock
import time
obj = RLock()
mutexA = obj
mutexB = obj
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(1)
mutexA.acquire()
print('%s 拿到A锁' % self.name)
mutexA.release()
mutexB.release()
if __name__ == '__main__':
for i in range(10):
t = Mythread()
t.start()
8.信号量
import time
import random
from threading import Thread, current_thread, Semaphore
mutex = Semaphore(5)
def task():
with mutex:
print('%s 在上厕所' % current_thread().name)
time.sleep(random.randint(1, 3))
if __name__ == '__main__':
for i in range(20):
t = Thread(target=task)
t.start()