一,线程Thread模块
1.效率更高(相对于进程)
import time
from multiprocessing import Process
from threading import Thread
def func(a):
a=a+1 if __name__=="__main__":
start=time.time()
t_l=[]
for i in range(50):
t=Thread(target=func,args=(i,))
t_l.append(t)
t.start()
for t in t_l:
t.join()
print("主线程结束")
print(time.time()-start) # 0.010993003845214844 start=time.time()
p_l=[]
for i in range(50):
p=Process(target=func,args=(i,))
p_l.append(p)
p.start()
for p in p_l:
p.join()
print("主进程")
print(time.time()-start) # 6.235144376754761
2.线程之间的数据共享   (进程中数据是隔离的):
from threading import Thread
n=100
def func():
global n #子线程引用主线程的变量 (进程中不可以引用)
n=n-1 #并修改主线程的变量值 t_l=[]
for i in range(100):
t=Thread(target=func)
t_l.append(t)
t.start()
for t in t_l:
t.join()
print(n) #
3.守护线程
import time
from threading import Thread
def func1():
while True:
print("True") #4.打印True 11.** 13.**
time.sleep(0.5) # 5.睡1 秒 #12.又休1秒 14.又休1秒 def func2():
print("in f2 start") #8打印in f2 start
time.sleep(3) #9,休3秒
print("in f2 end") #15打印 in f2 end t1=Thread(target=func1) #1.创建一个线程
t1.setDaemon(True) #2.设置成守护进程
t1.start() #3.申请开启线程
t2=Thread(target=func2) #6.创建另一个线程
t2.start() #7.申请开启另一个线程
time.sleep(1) # 12.**
print('主线程') #10. 打印主线程总结:主线程如果结束了,那么整个进程就结束,所有线程就结束
    守护进程:只守护主进程的代码就可以了,守护进程会在主进程的代码执行完毕之后直接结束,无论守护进程是否执行完毕

4.开启线程的第二种方式:
import time
from threading import Thread,get_ident
class MyThread(Thread):
def __init__(self,args):
super().__init__()
self.args=args def run(self):
print("in my thread:" ,get_ident(), self.args)
print("in main",get_ident()) # in main 11676
m=MyThread("hahaha")
m.start() # in my thread: 22100 hahaha
5.Thread类的其他方法
Thread实例对象的方法:
isAlive():返回线程是否执行
getName():返回线程名
setName():设置线程名 threading模块提供的一些方法:
threading.currentThread():返回当前的线程变量
threading.enumerate():返回一个包含正在运行的线程的list,正在运行指线程启动后、结束前,不包括启动前和终止后的线程
threading.activeCount() :返回正在运行的线程数量,与len(threading.enumerate())有相同的结果
示例:
import time
import threading
from threading import Thread,get_ident,currentThread
print(threading.currentThread().getName()) # MainThrea
print(threading.enumerate()) #[<_MainThread(MainThread, started 9780)>]
print(threading.activeCount()) #
二.线程中的锁 Lock
1. 什么时候用锁:
在多个进程\线程同时访问一个数据的时候就会产生数据的不安全的现象
2.区别GIL 全局解释器锁
在同一个进程里的每一个线程同一时间只能有一个线程访问CPU
3.尽量不要设置全局变量
只要在多线程/进程之间用到全局变量,就加上锁
第一版:
import time
import threading
from threading import Thread,get_ident,currentThread
print(threading.currentThread().getName()) # MainThrea
print(threading.enumerate()) #[<_MainThread(MainThread, started 9780)>]
print(threading.activeCount()) #
第二版:科学家吃面:
1.死锁现象:
所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,
它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程
import time
from threading import Thread,Lock
lock=Lock()
noodle_lock=Lock()
fork_lock=Lock()
def eat1(name):
noodle_lock.acquire()
print("%s拿到了面" % name)
fork_lock.acquire()
print("%s拿到了叉子"%name)
print("%s在吃面"%name)
time.sleep(0.5)
fork_lock.release()
noodle_lock.release() def eat2(name):
fork_lock.acquire()
print("%s拿到了叉子"%name)
noodle_lock.acquire()
print("%s拿到面条"%name)
print("%s在吃面"%name)
time.sleep(0.5)
noodle_lock.release()
fork_lock.release()
eat_l=["alex","wusir","太白","苑"]
for name in eat_l:
Thread(target=eat1,args=(name,)).start()
Thread(target=eat2,args=(name,)).start()
2.递归锁(Rlock):
递归锁,在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。
这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一
个线程所有的acquire都被release,其他的线程才能获得资源
3.用递归锁解决上述死锁问题:
import time
from threading import Thread,RLock
lock=RLock() def eat1(name):
lock.acquire()
print("%s拿到了面" % name)
lock.acquire()
print("%s拿到了叉子"%name)
print("%s在吃面"%name)
time.sleep(0.5)
lock.release()
lock.release() def eat2(name):
lock.acquire()
print("%s拿到了叉子"%name)
lock.acquire()
print("%s拿到面条"%name)
print("%s在吃面"%name)
time.sleep(0.5)
lock.release()
lock.release()
eat_l=["alex","wusir","太白","苑"]
for name in eat_l:
Thread(target=eat1,args=(name,)).start()
Thread(target=eat2,args=(name,)).start()

4.互斥锁解决死锁问题
import time
from threading import Thread,Lock
lock=Lock() def eat1(name):
lock.acquire()
print("%s拿到了面" % name)
print("%s拿到了叉子"%name)
print("%s在吃面"%name)
time.sleep(0.5)
lock.release() def eat2(name):
lock.acquire()
print("%s拿到了叉子"%name)
print("%s拿到面条"%name)
print("%s在吃面"%name)
time.sleep(0.5)
lock.release() eat_l=["alex","wusir","太白","苑"]
for name in eat_l:
Thread(target=eat1,args=(name,)).start()
Thread(target=eat2,args=(name,)).start()
面试题:
互斥锁和递归锁哪个好:
递归锁 快速恢复服务
死锁问题的出现是程序的设计或者逻辑的问题
还应该进一步的排除和重构逻辑来保证使用互斥锁也不会发生死锁
互斥锁与递归锁的区别:
互斥锁:就是在一个线程中不能连续多次acquire
递归锁:可以在同一个线程中acquire任意次,注意acquire多少次就需要release多少次
三.线程中的信号量 Semaphore
信号量: 锁 + 计数器
信号量 VS 进程池
 import time
from multiprocessing import Semaphore,Process,Pool
def ktv1(sem,i):
sem.acquire()
i+=1
sem.release()
def ktv2(i):
i+=1
if __name__=="__main__":
#信号量
sem=Semaphore(5)
start=time.time()
p_l=[]
for i in range(100):
p=Process(target=ktv1,args=(sem,i))
p.start()
p_l.append(p)
for p in p_l:
p.join()
print("###",time.time()-start) # 7.551328897476196
#进程池
start=time.time()
p = Pool(5)
for i in range(100):
ret=p.apply_async(func=ktv2,args=(p,i))
p.close()
p.join()
print("@@@",time.time()-start) #@@@ 1.013512372970581
Thread信号量:
import time
from threading import Semaphore,Thread
def ktv1(sem, i):
sem.acquire()
i += 1
sem.release()
def ktv2(i):
i += 1
if __name__ == "__main__":
sem = Semaphore(5)
start = time.time()
p_l = []
for i in range(100):
t = Thread(target=ktv1, args=(sem, i))
t.start()
p_l.append(t)
for t in p_l:
t.join()
print("###", time.time() - start) # ### 0.01998734474182129
总结:
进程池
进程池的效率更高;
池子里有几个就起几个
不管多少任务,池子的个数是固定的
开启进程和关闭进程这些事都是需要固定的开销的
不产生额外的时间开销
信号量:
有多少任务就起多少进程/线程
可以帮助你减少操作系统切换的负担
但是并不能帮助你减少进程/线程开启和关闭的时间
四.线程中的事件 Event
事件四个方法:
wait : 等到事件内部的信号变成True就不阻塞了,
set: 设置信号为True
clear : 设置信号变成False
is_set : 查看信号是否为True
示例:
import time
import random
from threading import Thread,Event
def check(e):
print("正在检测两台机器之间的网络情况")
time.sleep(random.randint(0,2))
e.set() def connect_db(e):
n = 0
while n < 3:
if e.is_set():
break
else:
e.wait(0.5)
n += 1
if n == 3:
raise TimeoutError
print('连接数据库 ... ')
print('连接数据库成功~~~')
e=Event()
Thread(target=connect_db,args=(e,)).start()
Thread(target=check,args=(e,)).start()
五.条件 Condition
condition :
Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方法。线程首先acquire一个
条件变量,然后判断一些条件。如果条件不满足则wait;如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,
其他处于wait状态的线程接到通知后会重新判断条件。不断的重复这一过程,从而解决复杂的同步问题。
condition 的相关方法
acquire
release
wait 阻塞
notify 让wait解除阻塞的工具
在执行wait和notify这两个方法的前后 必须执行acquire和release
from threading import Condition,Thread
def func(con,i):
con.acquire()
con.wait()
print("threaing:",i)
con.release() con=Condition()
for i in range(20):
Thread(target=func,args=(con,i)).start()
con.acquire()
con.notify_all()
con.release()
while True:
num=int(input("num>>>"))
con.acquire()
con.notify(num)
con.release()
六.定时器 Timer
指定n秒后执行某个操作
from threading import Timer
def func():
print("in func,执行吧")
Timer(1,func).start()

七.多线程起socket(tcp)

服务器代码

import socket
import os
sk=socket.socket()
sk.connect(("127.0.0.1",9991))
while True:
print(sk.recv(1024))
sk.send(str(os.getpid()).encode('utf-8'))
sk.close()
客户端代码
import socket
import os
sk=socket.socket()
sk.connect(("127.0.0.1",9991))
while True:
print(sk.recv(1024))
sk.send(str(os.getpid()).encode('utf-8'))
sk.close()

python全栈开发 * 线程锁 Thread 模块 其他 * 180730的更多相关文章

  1. python 全栈开发,Day42(Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures)

    昨日内容回顾 线程什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线程是什么关系? 线程是在进程中的 一个执行单位 多进程 本质上开启的这个进程里就有一个线程 多线程 单纯的在当 ...

  2. Python全栈开发 线程和进程

    一.线程 线程是程序工作的最小单元,由进程生成,生成的线程间会共享内存空间.Python中创建线程比较简单,导入threading模块,创建线程实例.下面这段代码是一个简单的多线程例子 import ...

  3. python全栈开发 * 线程队列 线程池 协程 * 180731

    一.线程队列 队列:1.Queue 先进先出 自带锁 数据安全 from queue import Queue from multiprocessing import Queue (IPC队列)2.L ...

  4. python全栈开发day34-线程Thread

    一.昨日内容回顾 1. 概念和理论 进程是计算机资源分配最小单位 进程三状态.同步.异步.阻塞.非阻塞 2. 进程的创建 实例化.自建类run,start,join,terminate,daemon等 ...

  5. Python全栈开发【re正则模块】

    re正则模块 本节内容: 正则介绍 元字符及元字符集 元字符转义符 re模块下的常用方法 正则介绍(re) 正则表达式(或 RE)是一种小型的.高度专业化的编程语言. 在Python中,它内嵌在Pyt ...

  6. python全栈开发-json和pickle模块(数据的序列化)

    一.什么是序列化? 我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flat ...

  7. python 全栈开发,Day31(re模块)

    回顾昨天的内容 异常处理 try except 一定要在except之后写一些提示或者处理的内容 try: '''可能会出现异常的代码''' except ValueError: '''打印一些提示或 ...

  8. python全栈开发中级班全程笔记(第二模块、第四章)(常用模块导入)

    python全栈开发笔记第二模块 第四章 :常用模块(第二部分)     一.os 模块的 详解 1.os.getcwd()    :得到当前工作目录,即当前python解释器所在目录路径 impor ...

  9. Python全栈开发【模块】

    Python全栈开发[模块] 本节内容: 模块介绍 time random os sys json & picle shelve XML hashlib ConfigParser loggin ...

随机推荐

  1. [Python设计模式] 第16章 上班,干活,下班,加班——状态模式

    github地址:https://github.com/cheesezh/python_design_patterns 题目 用代码模拟一天的工作状态,上午状态好,中午想睡觉,下午渐恢复,加班苦煎熬. ...

  2. 使用Git Subtree在多个项目中共用同一个子项目

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/8427796.html 场景一:已有一个大项目,需要把其中一部分内容独立出来作为共用子项目,被其他项目引用 一: ...

  3. SQL Server里如何处理死锁

    在今天的文章里,我想谈下SQL Server里如何处理死锁.当2个查询彼此等待时会发生死锁,没有一个查询可以继续它们的操作.首先我想给你大致讲下SQL Server如何处理死锁.最后我会展示下SQL ...

  4. Ubuntu 16.04 升级git

    To update git on Ubuntu 12.04 just follow this line of commands: sudo apt-get install python-softwar ...

  5. linux随机数生成

    随机数多应用在密码的随机生成 #随机数生成 $RANDOM (1-32767) 11.内部系统变量($RANDOM) 1-32767 22. awk 'BEGIN{srand();print rand ...

  6. 微信小程序 this.setData is not a function

    在一般的函数中: bindFaChange1: function (e) { console.log('picker发送选择改变,携带值为', e.detail.value) this.setData ...

  7. css 定位(fixed > absolute > relative)与层级zIndex 的权限认知

    原则1: fixed > absolute > relative原则2: zIndex 越高越牛逼,不管你是谁无视身份.原则3: 青出于蓝而胜于蓝,儿子永远比父亲强原则4: 平台很重要. ...

  8. thymeleaf th:href 多个参数传递格式

    今天在使用thymeleaf的th:href传递多个参数的时候困惑了.然后百度了一下,发现没有人注释说明怎么弄,然后自己google了一下,现在就标记一下,方便记录一下. th:href=" ...

  9. APK优化工具zipalign的详细介绍和使用

    什么是Zipalign?      Zipalign是一个android平台上整理APK文件的工具,它首次被引入是在Android 1.6版本的SDK软件开发工具包中.它能够对打包的Android应用 ...

  10. 【OCR技术系列之五】自然场景文本检测技术综述(CTPN, SegLink, EAST)

    文字识别分为两个具体步骤:文字的检测和文字的识别,两者缺一不可,尤其是文字检测,是识别的前提条件,若文字都找不到,那何谈文字识别.今天我们首先来谈一下当今流行的文字检测技术有哪些. 文本检测不是一件简 ...