python的多线程编程之锁

1、 背景概述

上篇文章里, 着重叙说了编程的某些基本方面, 然而其中欠缺有关锁的相关概念, 所以在这篇文章里予以补充。

因为存有GIL, 即全局解释器锁, 所以每次获取CPU时, 仅有一个线程能够获取CPU运行权, 并在这方面被视作线程安全。然而在线程运行期间, 它可共享内存, 并具备一致的数据信息内容;如此这般, 此时的线程便不再那么安全了。

在其中, 需确保数据的准确无误, 而且要由自身来把控数据, 要针对数据施行加锁操作, 并且由自身去释放那一锁。

主要目的成了多线程往不太相关方向使用以提升使用效果, 比如爬虫时, 能借助它来抓取, 因线程间不存在需共同处理的数据, 所以抓取时使用它是最佳的 , 也就是为了提高性能与速度。

如果需要操作同一份数据,那么必须自己保证数据的安全性。

要是存在利用多cpu特性的诉求, 那应当采用的是多进程编程, 而非多线程编程, 多进程编程是这样的。

2、 利用锁进行同步相同的数据

直接看以下的代码:

python 复制代码
#!/usr/bin/env python
import time
import threading
num = 0
class MyThread(threading.Thread):
    def run(self):
        #lock.acquire()
        #time.sleep(1)
        global num
        num += 1
        print self.name + 'set num to '+str(num)
        #lock.release()
#lock = threading.RLock()
threads = []
for i in range(10000):
    t = MyThread()
    threads.append(t)
for i in range(10000):
    threads[i].start()
for i in range(10000):
    threads[i].join()

瞧一瞧上面所呈现的代码, 针对全局变量开展一处修改, 借此使得每个线程获取到的皆是同一份的数据, 由此一来, 极有可能致使数据的计算结果出现不正确的状况, 故而, 必须借助锁去把控数据的正确性。

需注意, 于我的机器上展开运行操作时, 均为正确的情形, 进而像是即便不用锁也能够达成, 然而在部分机器上开展模拟操作时, 最终的计算结果却并非正确的。

在使用锁的时候,只要将注释的代码进行去掉即可使用锁。

3、 锁的类型

在的模块中,提供了三种锁,如下所示:

做锁的操作期间, 于每个线程, 要自行去获取锁, 其后还得自己去释放锁, 不然的话会致使一直处于等待状态, 这也能够称作死锁。

4、 事件

以线程来做事情时, 能够去断定一个事件已然出现, 接下去促使触发去开展另有别样的事宜, 如此一来能借助event, 像下面呈现的代码那样呢:

python 复制代码
[root@python 523]# cat thread_demo.py 
#!/usr/bin/env python
import threading
import time
import Queue
def producter(name,queue,lock):
    event.clear()
    print '%s start to product...' % name
    queue.put('something')
    time.sleep(3)
    print 'product something'
    event.set()
    event.wait()
def consumer(name,queue,lock):
    print '%s start to consume...' % name
    event.wait()
    queue.get()
    print 'consume something'
    event.set()
lock = threading.Lock()
queue = Queue.Queue(10)
event = threading.Event()
threads = []
threadsc = []
for i in range(1):
    t = threading.Thread(target=producter,args=('kel%s' % i,queue,lock))
    threads.append(t)
for i in range(1):
    threads[i].start()
for i in range(1):
    t = threading.Thread(target=consumer,args=('smile%s' % i,queue,lock))
    threadsc.append(t)
for i in range(1):
    threadsc[i].start()

当运用event之际, clear的意思是把flag设定成false, set的意思是设定成true, wait的意思是在flag为false时, 持续等候, 进而在尚无数据时, 始终进行等待。

这种可以做事件的触发。

问题:

于开展此实验之际, 要是线程产生错误, 可不那么能够关闭, 进而唯有杀掉进程才行, 进而能够运用如下命令:

python 复制代码
killall python

把进程给杀掉之际, 线程也一并杀掉, 然而, 线程是没办法被杀死的, 虽然能够使得进程遭受杀害处理。

相关推荐
张张123y5 小时前
后端第一课:输入 URL 后发生了什么?我用手写 Socket 把全链路跑通了
python·websocket·ai·socket·url·后端开发
全栈弄潮儿7 小时前
Python实战第7期:字典与集合
后端·python·编程语言
2603_965148118 小时前
电商选品调研:通过关键词搜索API获取市场热销商品,结合商品详情API分析竞品卖点与定价
开发语言·数据库·人工智能·python·信息可视化
xixiaoyunya8 小时前
Python 异步编程入门:用 asyncio 轻松实现并发任务
开发语言·python·php
把我格子衫拿来8 小时前
Dice 很高就够了吗?分割评价中的 IoU、表面距离与 HD95
python·图像分割·模型评估·医学影像·dice
曲径海盗9 小时前
【Python 学习第 31 天】复习:变量与数据类型 等 3 题
python·学习笔记·编程入门
Data_Journal9 小时前
如何绕过 Cloudflare:网页抓取的最佳方法
网络·python
我命由我1234510 小时前
智能助手通用问答边界
人工智能·python·学习·ai·学习方法·ai编程·智能体
Angeldream12310 小时前
第 4 章 医学影像预处理
图像处理·人工智能·python·医学影像·医学影像处理
Web3&Basketball10 小时前
实测Gemini4Argon:ERQA 87%登顶长程任务榜
数据库·python·大模型·多模态·gemini·长上下文·推理优化