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

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

相关推荐
1 小时前
Python 图片处理:裁剪缩放至300×200,格式JPG/PNG/GIF,控制大小≤100KB
linux·前端·python
2601_962294611 小时前
Python工具软件开发:借助InsCode AI IDE开启智能编程新时代
ide·python·ai·开发工具·智能化编程
2601_962097363 小时前
GraphQL,Grafana和Dash
python·grafana·数据可视化·graphql·dash
benchmark_cc11 小时前
REST API 和 Python SDK 应该怎么选?量化交易数据接口选型实战
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
2601_9623824312 小时前
python快乐编程网络爬虫课后答案
python·网络爬虫·学习工具·课后答案·刷题app
鹏哥带你干乡墅12 小时前
优选乡墅赋能培训平台如何帮助提升乡村建设?
大数据·人工智能·python
veminhe13 小时前
python调用接口获取网络信息
python
Allen_LVyingbo14 小时前
医疗AI基础2026-构建可靠智能体的编程路径(上)
大数据·数据库·人工智能·python·自动化
Rnan-prince14 小时前
堆与TopK · 从零到通透 —— 9 节全系列复盘
python·算法