41章 -并发编程3互斥锁/线程理论/创建线程/join方法/守护线程/GIL全局解释器锁


41章

  • 互斥锁
  • 线程理论
  • 创建线程的两种方式
  • 多线程实现tcp服务端并发
  • join方法
  • 同一个进程下线程间数据共享
  • 线程对象相关方法
  • 守护线程
  • GIL全局解释器锁

互斥锁

  • 互斥锁定义

互斥锁是一种数据结构,使你可以执行一系列互斥操作。
  • 强调

互斥锁只应该出现在多个程序操作数据的地方 其他位置尽量不要加
ps:以后我们自己处理锁的情况很少 只需要知道锁的功能即可
  • 互斥锁作用

将并发变成穿行,虽然牺牲了程序的执行效率,但是保证了数据安全
  • 互斥锁使用

from multiprocessing import Process, Lock
mutex = Lock()
mutex.acquire()  # 抢锁
mutex.release()  # 释放锁
名称作用
行锁一锁锁一行或者多行数据
表锁一锁锁一整张表
乐观锁乐观锁是对于数据冲突保持一种乐观态度,操作数据时不会对操作的数据进行加锁
悲观锁观锁是基于一种悲观的态度类来防止一切数据冲突,它是以一种预防的姿态在修改数据之前把数据锁住,然后再对数据进行读写,在它释放锁之前任何人都不能对其数据进行操作

线程理论

名称作用
进程是资源单位 进程相当于是车间 进程负责给内部的线程提供相应的资源
线程线程相当于车间的流水线,线程负责执行真正的功能

创建线程的两种方式

前言:
开设线程不需要完整拷贝代码 所以无论什么系统都不会出现反复操作的情况
也不需要在启动脚本中执行 但是为了兼容性和统一性 习惯在启动脚本中编写

from threading import Thread
from multiprocessing import Process
import  time
----------------------------------------------
class MyThread(Thread):
    def __init__(self, name):
        super().__init__()
        self.name = name

    def run(self):
        print(f'{self.name}正在运行')
        time.sleep(3)
        print(f'{self.name}运行结束')


obj = MyThread('jason')
obj.start()
print('主线程')
---------执行结果-----------
jason正在运行
主线程
jason运行结束

------------------------------------------------------

# def task(name):
#     print(f'{name}正在运行')
#     time.sleep(3)
#     print(f'{name}运行结束')

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

多线程实现TCP 服务端并发

比多进程更加简单方便,消耗的资源更少
ps:课下使用多进程或者多线程对比(任务管理器)

join方法

主线程等到子线程运行结束 之后再运行
from threading import Thread
import time
def task():
print('正在执行')
time.sleep(3)
print('运行结束')

t =  Thread(target=task)
t.start()
t.join()
print('主线程')

同一个进程下线程数据共享

from threading import Thread
money = 1000
def func():
	global money
	money = 666
	
t = Thread(target = func)
t.start()
t.join()
print(money)

线程对象相关方法

1.进程号
 同一个进程下开设的多个线程拥有相同的进程号
2.线程名
from threading import Thread,current_thread
current_thread().name

主:MainThread 
子:Thread-N

3.进程下的线程数
active_count()

守护线程

  • 定义

守护线程伴随着被守护的线程的结束而结束
from  threading import Thread
import time
def task():
print('子线程运行task函数')
time.sleep(3)
print('子线程运行task结束')

GIL全局解释器锁

储备知识
​ 1.python 解释器 也是由编程语言写出来。
​ Cpython 用c写出来
​ Jpython 用java写出来的
​ Pypython 用py写出来的

	
ps:最常用的就是Cpython(默认)
#官方文档对GIL的解释
In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)


参考群内截图 理解上述3、4解读
1.误解:python的多线程就是垃圾 利用不到多核优势
	python的多线程确实无法使用多核优势 但是在IO密集型的任务下是有用的
2.误解:既然有GIL 那么以后我们写代码都不需要加互斥锁
	不对 GIL只确保解释器层面数据不会错乱(垃圾回收机制)
	针对程序中自己的数据应该自己加锁处理
3.所有的解释型编程语言都没办法做到同一个进程下多个线程同时执行
ps:我们平时在写代码的时候 不需要考虑GIL 只在学习和面试阶段才考虑!!!

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/279833.html

(0)
上一篇 2022年8月11日
下一篇 2022年8月11日

相关推荐

发表回复

登录后才能评论