1.多任务编程

除了计算性能和图形显示以外,树莓派区别于Arduino的一大特点就是运行多任务操作系统。通过多任务系统用户可以同时执行多个互相独立的程序(任务),来完成不同的操作。

利用Python的多任务编程可以方便地实现并行运算,同时充分利用树莓派的多个内核。当然这里面有一些是真的并行操作,还有通过分时轮流使用CPU来实现的“伪并行”。

1.1.多线程编程

多线程操作的特点是简单易用,可用于处理CPU占用率不高的任务。虽然一个进程中可以建立多个线程,但由于同一个Python进程只能目前利用一个CPU内核,因此只能利用树莓派25%的CPU资源。这里例举两种多线程模块和threading。thread模块是比较底层的模块,threading模块对thread做了一些包装,以方便调用。需要注意的是Python3.x中已经不再支持thread模块,请使用threading实现多线程操作。

thread模块编程示例:

import thread

import time

def thread1():

while True:

print("\nThis is thread1!")

time.sleep(1)

def thread2():

while True:

print("\nThis is thread2!")

time.sleep(2)

thread.start_new_thread(thread1, ())

thread.start_new_thread(thread2, ())

while True:

print("\nThis is the main thread!")

time.sleep(4)

运行效果

threading模块编程示例:

import threading

import time

def my_thread():

for i in range(0, 4):

print("\nThis is a sub thread!")

time.sleep(1)

thread1 = threading.Thread(target = my_thread, args = ())

thread2 = threading.Thread(target = my_thread, args = ())

thread1.start()

thread2.start()

thread1.join()

thread2.join()

print("\nThis is the main thread!")

代码中的start()函数用于启动线程,join()用于等待线程结束。

运行效果

另外thread模块还有一种timer方式,可以延时一段时间再启动线程,代码示例如下:

import threading

import time

def thread_timer():

print("\nThis is a timer thread!")

thread_tm = threading.Timer(3, thread_timer)

thread_tm.start()

for i in range(0, 5):

print("\nThis is the main thread!")

time.sleep(1)

运行效果

1.2.Fork进程操作

我们在上一节中提到了,python的多线程操作只能利用一个CPU内核的资源。如果想要使用树莓派2的全部资源,方法之一就是使用fork创建多个进程。下面的代码演示了简单的fork操作。

import os, time

pid = os.fork()

# New created child process, fork() returns 0

if pid == 0:

print("I'm the child process, PID = %d" % os.getpid())

time.sleep(5)

exit(0)

# Parent process, fork() returns PID of created child

else:

child_pid = pid

print("I'm the parent process, PID = %d\n--> My new created child is %d" % (os.getpid(), child_pid))

time.sleep(1)

print("Waiting for the child...")

os.waitpid(child_pid, 0)

print("Child has finished!")

与thread和threading不同的是,在这里os.fork()的作用是克隆出一个子进程,也就是不管新建的进程还是原有的进程,都会执行fork后面相同的代码。通过对os.fork()的 返回值即可判断该进程为新建立的子进程(返回0)还是原有的父进程(返回子进程的PID)。

os.waitpid()则用来等待子进程结束,和thread中的jion()类似。

图 运行效果

进程间通信不想线程那样简单,可以使用全局变量。想要在不同的进程间传输信息,就需要使用特有的机制。下面的例子介绍了通过os.pipe()实现两个进程之间通信的方法:

import os, time

# Create pipes for data transmitting

(r, w) = os.pipe()

(r, w) = os.fdopen(r, 'r'), os.fdopen(w, 'w')

pid = os.fork()

# New created child process, fork() returns 0

if pid == 0:

r.close()

for i in range(10):

print("[Child] Sending msg to parent..." % i)

w.write("Hello!\n" % i)

w.flush()

time.sleep(1)

# Parent process, fork() returns PID of created child

else:

w.close()

while True:

msg = r.readline()

if not msg: break

print("[Parent] Msg from child[PID%d]: %s" %(pid, msg))

示例代码中建立了r、w两个通道,并通过w.write()和r.readline()来进行写入和读取操作。同样的使用fork建立子进程,在子进程中写入字符串信息而不需要读取,因此关闭r通道只保留w通道;在父进程中只用读取子进程发来的信息,因此关闭w通道。

图 运行效果

1.3.Multiprocessing模块

对于初学者来说,在使用fork建立多个子进程时可能不容易理清代码关系。除了os.fork()功能以外,Python中还拥有专用于多任务处理的multiprocessing模块。在下面代码中可以看出,multiprocessing在建立process时和前面的threading模块中建立线程的方式类似。

import multiprocessing as mp

import time, os

def my_process(num):

print("I'm process no.%d, PID = %d." %(num, os.getpid()))

time.sleep(3)

print("Creating new processes...")

p1 = mp.Process(target=my_process, args=(1,))

p2 = mp.Process(target=my_process, args=(2,))

p3 = mp.Process(target=my_process, args=(3,))

p1.start()

p2.start()

p3.start()

print("Waiting for all the processes...")

p1.join()

p2.join()

p3.join()

图 运行效果

multiprocessing中也集成了pipe功能,用于进程间的通信。同时我们还可以使用队列(queue)来实现不同进程的数据传输。下面代码建立了reader_p子进程用来读取queue中的数据,并在父进程中向queue中写入数据。与pipe不同,代码中的两个进程共享同一个queue。而写入和读取数据的函数也变成了put()和get()。

import multiprocessing as mp

import time

# Read msg from the queue and print it out

def reader(queue):

while True:

msg = queue.get()

if (msg == 'DONE'):

break

print("[Reader]Get msg from writer: %s" % msg)

# Write msg with number into the queue

def writer(queue):

print("[Writer] Sending msg to reader...")

for i in range(0, 5):

queue.put("Hello !" % i)

time.sleep(1)

queue.put('DONE')

queue = mp.Queue()

print("Create new process as reader!")

reader_p = mp.Process(target=reader, args=((queue),))

reader_p.daemon = True

reader_p.start()

writer(queue)

reader_p.join()

程序运行后,reader_p进程开始监控队列中的数据,知道接收到字符串“DONE”后退出。父进程向队列中发送一组数据,最后等待子进程结束后退出。

图 运行效果

python多进程编程_【玩树莓】编程篇(八)Python多线程、多进程编程相关推荐

  1. python大游戏_玩游戏就能学Python?太炫酷了!

    原标题:玩游戏就能学Python?太炫酷了! 要说现在最火的语言,那一定是Python了. 各种排行榜里,Python的排名都是蹭蹭蹭地往上涨.Python也确实是最适合新手入门的语言了,语法简单,应 ...

  2. python docker自动化_「docker实战篇」python的docker爬虫技术-移动自动化控制工具appium工具(17)...

    原创文章,欢迎转载.转载请注明:转载自 IT人故事会,谢谢! 原文链接地址: 「docker实战篇」python的docker爬虫技术-移动自动化控制工具appium工具(17) Appium是一个开 ...

  3. python docker自动化_「docker实战篇」python的docker爬虫技术-移动自动化控制工具安卓ADB的使用(15)...

    原创文章,欢迎转载.转载请注明:转载自 IT人故事会,谢谢! 原文链接地址: 「docker实战篇」python的docker爬虫技术-移动自动化控制工具安卓ADB的使用(15) adb(Androi ...

  4. python 柱状图 间距_专题第18篇:Python 绘图入门

    我的施工之路 1我的施工计划2数字专题3字符串专题4列表专题5流程控制专题6编程风格专题7函数使用8面向对象编程(上篇)9面向对象编程(下篇)10十大数据结构11包和模块使用总结12Python正则专 ...

  5. python docker实战_「docker实战篇」python的docker-docker镜像的创建使用dockerfile(3

    从上篇docker commit学习可以了解到,镜像的定制其实每一层添加的配置和文件,如果把每一层的修改配置,修改文件,都写入脚本,用这个脚本构建定制镜像,无法重复的问题,镜像构建透明性的问题,体积的 ...

  6. 群晖nas介绍文档_手把手带你玩转NAS 篇八:NAS文档随身带——多终端文件同步介绍(群晖drive篇)...

    手把手带你玩转NAS 篇八:NAS文档随身带--多终端文件同步介绍(群晖drive篇) 2020-01-08 15:23:44 24点赞 214收藏 31评论 你是AMD Yes党?还是intel和N ...

  7. Python灰帽子_黑客与逆向工程师的Python编程之道

    收藏自用 链接:Python灰帽子_黑客与逆向工程师的Python编程之道

  8. 玩游戏学python的网站_娱教于乐!四大游戏类编程网站,学Python再也不枯燥无味了...

    前言 学习编程虽然对有些人来说是件乐事,但是对大多数人来说仍然是一件比较枯燥困难的事情.当然,面临这样困惑的人,并不是只有你一个,所以,这世界上就出现了许多寓教于乐的通过游戏的形式来教你编程的网站.让 ...

  9. 99 网络编程_传统网络工程师如何利用python实现公司内网IP地址信息查询?

      网   工   圈 网络工程师阿龙圈内最早的公益公众号,本号已认证!学网络关注我一个就够了(关注近5w+)关注听说99%的网工都来这里充电吖关注我,一个老HCIE(编号3558)带你轻松玩网络技术 ...

  10. 免费学python编程_强力推荐,非常全的 Python编程学习资料(今日免费)

    因为大数据和 AI,Python 一跃成为最火的语言,这里推荐几本畅销排行榜上的好书. 有需要在我的头条号,私信我,"Python",即可免费领取. 一.Python基础教程 &l ...

最新文章

  1. 【深度学习】基于Pytorch的softmax回归问题辨析和应用(一)
  2. 已知圆心 坐标和一点坐标和角度 就之后的坐标_《6. AutoCAD 标注角度尺寸》
  3. xfce的面板调节声音大小的按钮不见了。
  4. One order deletion tool
  5. 基于Docker搭建Redis集群(主从集群)
  6. uvicorn 更改fastapi 运行host和port
  7. php 自定义打印模板下载,PHP – 创建自定义模板系统?
  8. kali linux 2019.1 替换burpsuite pro 1.7.37
  9. idea 报错is already defined as class
  10. 简易新闻网站NewsWeb-网页抓取
  11. 只显示 前100个字 java 实现截取字符串!使用! c:if test=${fn:length(onebeans.info)100 }${ fn:substri...
  12. 深入浅出MVC框架模式
  13. 计算机培训心得ppt展示,ppt制作学习心得
  14. Java的企业级开发项目--OA办公系统
  15. openflow pox操作命令
  16. SAP系统销售流程成本和收入的确认
  17. 英特尔无线蓝牙启动服务器,如何在英特尔Edison上部署蓝牙安全网关
  18. R 回归 虚拟变量na_R语言 | 生存分析之R包survival的单变量和多变量Cox回归
  19. 三角函数曲线(含具体分析过程)
  20. 【NOIP2013模拟】Freda的传呼机

热门文章

  1. 施乐D95服务器系统,d125(施乐d95和d125哪款稳定)
  2. DNS和BIND总结
  3. 【产品】设计时可用到的认知偏差与效应
  4. csp计算机专业,中国计算机学会推出CSP非专业级别认证
  5. 【开源共享】全网最简单易用的imx6ull烧写工具设计初衷工作原理设计前的思考
  6. [WebGL入门]二十六,纹理绘图
  7. js+css+html 抽奖页面
  8. 互联网晚报 | 12月20日 星期一 | 安踏100亿成立“和敏基金会”;阿里公布碳中和目标;京东上线数字藏品交易平台...
  9. S5pv210 出现一个离奇wince6.0 activesync 软件连接问题
  10. 【微信小程序】微信小程序提示Do not have handler in component