什么是线程
线程是操作系统最小的运算调度单位,被包含在进程中,一个线程就是一个固定的 执行流程
线程的进程的关系 重点
线程不能单独存在 必须存在于进程中,
进程是一个资源单位,其包含了运行程序所需的所有资源
线程才是真正的执行单位
没有线程,进程中的资源无法被利用起来,所以一个进程至少包含一个线程,称之为主线程
当我们启动一个程序时,操作系统就会自己为这个程序创建一个主线程
线程可以由程序后期开启 ,自己开启线程称之为子线程
为什么需要线程 重点
目的只有一个就是提高效率
就像一个车间 如果产量更不上 就在造一条流水线
当然可以再造一个新车间,那需要把原材料运过去 ,这个过程是非常耗时的
所以通常情况是创建新的流水线 而不是车间 即 线程
如何使用 重点
使用方法和多进程一模一样
不过开启线程的代码可以放在任何位置 开启进程必须放在判断下面
from threading import Thread,current_threadimport time?def task(): print("2",current_thread()) print("子线程running") time.sleep(10) print("子线程over")?# 使用方法一 直接实例化Thread类if __name__ == ‘__main__‘: t = Thread(target=task) t.start() # task() # 执行顺序不固定 如果开启线程速度足够快 可能子线程先执行 print("主线程over") print("1",current_thread())?# 使用方法二 继承Thread 覆盖run方法class MyThread(Thread): def run(self): print("子线程run!")m = MyThread()print("主线over")?# 使用方法和多进程一模一样 开启线程的代码可以放在任何位置 开启进程必须放在判断下面
线程的特点 重点
1.创建开销小
2.同一个进程中的多个线程数据时共享的
3.多个线程之间,是平等的没有父子关系 所有线程的PID都是相同的
# 创建线程开销对比import osfrom threading import Threadfrom multiprocessing import Process?import time??def task(): # print("hello") print(os.getpid()) pass?if __name__ == ‘__main__‘:? st_time = time.time()? ts = [] for i in range(100): t = Thread(target=task) # t = Process(target=task) t.start() ts.append(t)? for t in ts: t.join()? print(time.time()-st_time) print("主over")
守护线程 了解
一个线程可以设置为另一个线程的守护线程
特点: 被守护线程结束后守护线程也随之结束
# 守护线程会等到所有非守护线程结束后结束 ! 前提是除了主线程之外 还有后别的非守护# 当然如果守护线程已经完成任务 立马就结束了
from threading import Threadimport time?def task(): print("子1running......") time.sleep(100) print("子1over......")?def task2(): print("子2running......") time.sleep(4) print("子2over......") t = Thread(target=task)t.daemon = Truet.start()?t2 =Thread(target=task2)t2.start()?print("主over")
线程 互斥锁
共享意味着竞争
线程中也存在安全问题,
多线程可以并发执行,一旦并发了并且访问了同一个资源就会有问题
解决方案:还是互斥锁
案例:
from threading import Thread,enumerate,Lockimport time?number = 10?lock = Lock()?def task(): global number lock.acquire() a = number time.sleep(0.1) number = a - 1 lock.release()?for i in range(10): t = Thread(target=task) t.start()?for t in enumerate()[1:]: # print(t) t.join() print(number)
死锁问题
from threading import Lock, current_thread, Thread?""" 死锁问题 当程序出现了不止一把锁,分别被不同的线程持有, 有一个资源 要想使用必须同时具备两把锁 这时候程序就会进程无限卡死状态 ,这就称之为死锁 例如: 要吃饭 必须具备盘子和筷子 但是一个人拿着盘子 等筷子 另一个人拿着筷子等盘子 如何避免死锁问题 锁不要有多个,一个足够 如果真的发生了死锁问题,必须迫使一方先交出锁 """import time# 盘子lock1 = Lock()?# 筷子lock2 = Lock()?def eat1(): lock1.acquire() print("%s抢到了盘子" % current_thread().name) time.sleep(0.5) lock2.acquire() print("%s抢到了筷子" % current_thread().name)? print("%s开吃了!" % current_thread().name) lock2.release() print("%s放下筷子" % current_thread().name)? lock1.release() print("%s放下盘子" % current_thread().name)??def eat2(): lock2.acquire() print("%s抢到了筷子" % current_thread().name)? lock1.acquire() print("%s抢到了盘子" % current_thread().name)?? print("%s开吃了!" % current_thread().name)?? lock1.release() print("%s放下盘子" % current_thread().name) lock2.release() print("%s放下筷子" % current_thread().name)??t1 = Thread(target=eat1)??t2 = Thread(target=eat2)?t1.start()t2.start()
可重入锁 了解
Rlock 称之为递归锁或者可重入锁
Rlock不是用来解决死锁问题的
与Lock唯一的区别:
Rlock同一线程可以多次执行acquire 但是执行几次acquire就应该对应release几次
如果一个线程已经执行过acquire 其他线程将无法执行acquire
?from threading import RLock, Lock, Thread?# l = Lock()## l.acquire()# print("1")# l.acquire()# print("2")??l = RLock()?# l.acquire()# print("1")# l.acquire()# print("2")?def task(): l.acquire() print("子run......") l.release()??# 主线程锁了一次l.acquire()l.acquire()?l.release()l.release()t1 = Thread(target=task)t1.start()
信号量 了解
?""" 信号量 了解Lock RLock?可以现在被锁定的代码 同时可以被多少线程并发访问Lock 锁住一个马桶 同时只能有一个Semaphore 锁住一个公共厕所 同时可以来一堆人??用途: 仅用于控制并发访问 并不能防止并发修改造成的问题"""?from threading import Semaphore, Threadimport time?s = Semaphore(5)def task(): s.acquire() print("子run") time.sleep(3) print("子over") s.release()?for i in range(10): t = Thread(target=task) t.start()
回顾
多线程
线程是CPU的最小执行单位, 线程本质是一堆代码构成的执行流程
线程被包含在进程中,
进程是一个资源单位,其中存储着该程序运行所需所有资源, 可以比喻为一个车间
线程就是车间中国一条流水线,上面放的是制作产品的具体方法(就是的代码)
一个进程至少有一个线程,操作系统在运行一个程序时 会在进程中自动开启一条线程
一个进程中可以有多个线程
同一个进程中的线程共享进程内的数据
创建线程速度非常快 开销小
线程之间没有父子关系 都是平等的
使用方式和进程一致
学习多线程 多进程 都是为了提高效率 ,通过并发执行多个任务
实现并发的方式,多线程和多进程
原文地址:https://www.cnblogs.com/haojunliancheng/p/10975357.html