Python多线程操作
来源:互联网 发布:高新区行知小学地址 编辑:程序博客网 时间:2024/05/01 02:21
每个线程互相独立,相互之间没有任何关系。现在假设这样一个例子:有一个全局的计数num,每个线程获取这个全局的计数,根据num进行一些处理,然后将num加1。很容易写出这样的代码:
# encoding: UTF-8import threadingimport timeclass MyThread(threading.Thread): def run(self): global num time.sleep(1) num = num+1 msg = self.name+' set num to '+str(num) print msgnum = 0def test(): for i in range(5): t = MyThread() t.start()if __name__ == '__main__': test()
但是运行结果是不正确的:
Thread-5 set num to 2
Thread-3 set num to 3
Thread-2 set num to 5
Thread-1 set num to 5
Thread-4 set num to 4
问题产生的原因就是没有控制多个线程对同一资源的访问,对数据造成破坏,使得线程运行的结果不可预期。这种现象称为“线程不安全”。
互斥锁同步
上面的例子引出了多线程编程的最常见问题:数据共享。当多个线程都修改某一个共享数据的时候,需要进行同步控制。
线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁。互斥锁为资源引入一个状态:锁定/非锁定。某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。
threading模块中定义了Lock类,可以方便的处理锁定:
#创建锁mutex = threading.Lock()#锁定mutex.acquire([timeout])#释放mutex.release()
其中,锁定方法acquire可以有一个超时时间的可选参数timeout。如果设定了timeout,则在超时后通过返回值可以判断是否得到了锁,从而可以进行一些其他的处理。
使用互斥锁实现上面的例子的代码如下:
import threadingimport timeclass MyThread(threading.Thread): def run(self): global num time.sleep(1) if mutex.acquire(1): num = num+1 msg = self.name+' set num to '+str(num) print msg mutex.release()num = 0mutex = threading.Lock()def test(): for i in range(5): t = MyThread() t.start()if __name__ == '__main__': test()
运行结果:
Thread-3 set num to 1
Thread-4 set num to 2
Thread-5 set num to 3
Thread-2 set num to 4
Thread-1 set num to 5
可以看到,加入互斥锁后,运行结果与预期相符。
- Python多线程操作
- python多线程操作【概念】
- python 多线程批量操作数据库测试
- Python多线程/多进程操作队列
- 一行 Python 实现并行化 -- 日常多线程操作的新思路
- 一行 Python 实现并行化 -- 日常多线程操作的新思路
- python 多线程遍历windows盘符下文件操作
- 一行 Python 实现并行化 -- 日常多线程操作的新思路
- python 多线程遍历windows盘符下文件操作
- 多线程操作
- 多线程操作
- 多线程操作
- Python多线程
- Python多线程
- Python多线程
- python多线程
- python 多线程
- python多线程
- 深入分析 Linux 内核链表(转)
- Hibernate各种主键生成策略与配置详解
- Fatal error: Call to undefined function randstr()
- Turn.js创建类似书本和杂志翻页效果
- android 中Message相关及其使用
- Python多线程操作
- Letter Combinations of a Phone Number
- linux下遍历目录树方法总结(下)
- Android备用知识
- 赢在测试2:中国软件测试专家访谈录
- 给树莓派增加一个Linux系统调用
- java高级工程师---------spring的知识重点
- opencv(一):VC6.0下安装与配置OpenCV1.0
- 动态设置滚动条高度宽度的方法[非润乾知识库方法]