前言

最近写一些模拟集群智能的算法,虽然机制简单,但是随着个体的增加,设计的计算量就比较大了,尤其是加上matplotlib进行动态展示,使得运算量骤增,看着画面也比较卡.之前想把算法转化成c++代码,利用qt进行展示,入了坑才发现不是一朝一夕之功,没办法,还是回到自己熟悉的python上看看能不能优化一下代码.然后买了<<Python 并行编程-第二版>>这本书从头学起,希望用两三个月把这个整个七七八八.我相信我能坚持下去,把这块骨头啃明白.算是一个学习笔记吧,加上一些自己的理解,如果有哪位看官看到此文,发现讲到不对的地方加以批评指正.

基于线程的并行

threading模块提供的Thread类

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})

主要的参数就三个:

  • target:线程要执行的目标函数
  • name:线程名
  • args:目标函数的参数

    下面是一个简单的例子:
import threading
import time
import random def sleep_out(i):
print("{}号程序开始执行\n".format(i))
num = random.randint(0, 10)
time.sleep(num)
print("{}号程序休息了{}s\n".format(i,num)) if __name__ == "__main__":
threads = []
for i in range(10):
t = threading.Thread(target=sleep_out, args=(i,), name="thread-{}".format(i))
threads.append(t) for t in threads:
t.start() for t in threads:
t.join()
-----------------------------------输出-----------------------------
0号程序开始执行 1号程序开始执行 2号程序开始执行 3号程序开始执行 4号程序开始执行 5号程序开始执行 6号程序开始执行 7号程序开始执行 8号程序开始执行
9号程序开始执行 8号程序休息了1s 7号程序休息了4s 6号程序休息了5s 2号程序休息了6s 4号程序休息了7s 0号程序休息了7s 3号程序休息了8s 1号程序休息了10s 9号程序休息了10s 5号程序休息了10s 进程已结束,退出代码0

线程开始执行使用start()方法,一旦线程开始执行,则运行会转入后台,主线程继续执行.而要等待一个线程结束,必须使用join()方法,该方法会让主线程进入等待状态,直到线程执行完毕,主线程才会继续执行.

我们将刚才的程序改写为:

import threading
import time
import random def sleep_out(i):
print("{}号程序开始执行\n".format(i))
num = random.randint(0, 10)
time.sleep(num)
print("{}号程序休息了{}s\n".format(i,num)) if __name__ == "__main__":
threads = []
for i in range(10):
t = threading.Thread(target=sleep_out, args=(i,), name="thread-{}".format(i))
threads.append(t)
t.start()
t.join()
-----------------------------------输出-----------------------------
0号程序开始执行 0号程序休息了6s 1号程序开始执行 1号程序休息了6s 2号程序开始执行 2号程序休息了8s 3号程序开始执行 3号程序休息了0s 4号程序开始执行 4号程序休息了5s 5号程序开始执行 5号程序休息了1s 6号程序开始执行 6号程序休息了8s 7号程序开始执行 7号程序休息了8s 8号程序开始执行 8号程序休息了10s 9号程序开始执行 9号程序休息了9s 进程已结束,退出代码0

start()方法和join()方法相辅相成,一般不能独立存在.

确定当前线程

使用currentThread().getName()方法会返回当前线程名.

继续在刚才的代码上修改:

import threading
import time
import random def sleep_out(i):
print("{}号程序开始执行\n".format(i))
print("当前线程为"+threading.currentThread().getName())
num = random.randint(0, 10)
time.sleep(num)
print("{}号程序休息了{}s\n".format(i,num)) if __name__ == "__main__":
threads = []
for i in range(10):
t = threading.Thread(target=sleep_out, args=(i,), name="thread-{}".format(i))
threads.append(t)
t.start()
t.join()
-----------------------------------输出-----------------------------
0号程序开始执行 当前线程为thread-0
0号程序休息了2s 1号程序开始执行 当前线程为thread-1
1号程序休息了2s 2号程序开始执行 当前线程为thread-2
2号程序休息了3s 3号程序开始执行 当前线程为thread-3
3号程序休息了1s 4号程序开始执行 当前线程为thread-4
4号程序休息了3s 5号程序开始执行 当前线程为thread-5
5号程序休息了1s 6号程序开始执行 当前线程为thread-6
6号程序休息了2s 7号程序开始执行 当前线程为thread-7
7号程序休息了1s 8号程序开始执行 当前线程为thread-8
8号程序休息了1s 9号程序开始执行 当前线程为thread-9
9号程序休息了4s 进程已结束,退出代码0

自定义线程类

我们可以创建继承Thread类的子类,再重新定义run()方法,实现自己需要的功能.

示例如下:

import time
import threading
from random import randint
import os def sleep_out(num):
time.sleep(num) class MyThreadClass(threading.Thread):
def __init__(self, name, duration):
threading.Thread.__init__(self)
self.name = name
self.duration = duration def run(self):
print("线程:" + self.name + "正在运行, 进程ID:" + str(os.getpid()))
sleep_out(self.duration)
print("线程" + self.name + "结束!!!") if __name__ == "__main__":
start_time = time.time()
threads = []
for i in range(10):
t = MyThreadClass(name="thread-{}".format(i), duration=randint(0, 5))
threads.append(t) for t in threads:
t.start() for t in threads:
t.join() print("-----{}-----".format(time.time() - start_time))
----------输出----------
线程:thread-0正在运行, 进程ID:11804
线程thread-0结束!!!
线程:thread-1正在运行, 进程ID:11804
线程:thread-2正在运行, 进程ID:11804
线程:thread-3正在运行, 进程ID:11804
线程:thread-4正在运行, 进程ID:11804
线程:thread-5正在运行, 进程ID:11804
线程:thread-6正在运行, 进程ID:11804
线程:thread-7正在运行, 进程ID:11804
线程:thread-8正在运行, 进程ID:11804
线程:thread-9正在运行, 进程ID:11804
线程thread-6结束!!!线程thread-8结束!!!
线程thread-5结束!!! 线程thread-7结束!!!
线程thread-9结束!!!
线程thread-2结束!!!线程thread-3结束!!! 线程thread-1结束!!!线程thread-4结束!!! -----5.019770860671997-----

最新文章

  1. jQuery Mobile 可折叠
  2. 学习zepto.js(原型方法)[2]
  3. 【转】SharePoint camel query查询 event 或者Calendar 日历列表的时候,怎么查询所有的重复发生的事件
  4. ZOJ 2770火烧连营——差分约束
  5. 【C语言】16-预处理指令2-条件编译
  6. redhat centos yum源的安装
  7. Skip StyleCop Warnings.
  8. iOS自学之NSOperation、NSOperationQueue、Background
  9. Java--获取request中所有参数的方法
  10. boost在自己主动确定数据类型(BOOST_TYPEOF和BOOST_AUTO)使用
  11. MS08_067漏洞学习研究
  12. Android自定义安全键盘
  13. AvalonJS前端开发源码
  14. mysql 服务【安装】【启动】【停止】【卸载】【重置密码】
  15. 一千行 MySQL 详细学习笔记
  16. linux进程管理总结
  17. BLE获取iphone mac地址的方法--【原创】
  18. Elasticsearch集群管理工具head插件安装
  19. Maven传递依赖的范围
  20. Spring的JavaMail实现异步发送邮件

热门文章

  1. 国产paozhu c++ web framework 正式版发布
  2. 【进阶篇】Redis实战之Jedis使用技巧详解
  3. 学习ASP.NET Core Blazor编程系列二十——文件上传(完)
  4. python之路50 ORM执行SQL语句 操作多表查询 双下线方法
  5. 聚合查询、分组查询、ORM中如何给表再次添加新的字段、F与Q查询、ORM查询优化、ORM事务操作、ORM常用字段类型、ORM常用字段参数、Ajax、数据编码格式(Content-Type)、ajax携带文件数据
  6. for循环 rang方法
  7. Linux c 获取U盘挂载路径
  8. Aspose的jar破解文档
  9. Linux基础介绍
  10. DVWA系列3:CSRF