【python学习】从海贼王中体会进程、线程和协程

二进制打工人
• 阅读 1162

【python学习】从海贼王中体会进程、线程和协程

在学习Python的过程中,一种最直接的感触就是上手轻松,但精通很难,很多时候离不开计算机学科的基础知识。比如下面这个问题,我是没法第一时间想到准确答案的。

  • 协程线程有什么区别?

在学习的道路上,看懂听懂是输入,写明说清是输出,只有达到输出这一步才算真正搞懂一个知识点。So,今天就先搞搞这个问题,用海贼王的故事来理解个中差异。

协程线程,我再加个进程

1 进程

进程(process)是一个执行中的程序。每个进程都拥有自己的地址空间、内存、数据栈以及其他用于跟踪执行的辅助数据。操作系统管理其上所有进程的执行,并为这些进程合理地分配时间。因为每个进程都拥有自己的内存和数据栈等,所以只能采用进程间通信(IPC)的方式共享信息。

进程,直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己独立的地址空间,有自己的堆,上级挂靠单位是操作系统。操作系统会以进程为单位,分配系统资源(CPU时间片、内存等资源),进程是资源分配的最小单位。

OK,下面就到了海贼show time。

话说路飞一行人从新手村开始,斩世界政府旗帜,闯海军本部,灭七武海,挑四皇,一直打怪升级,练就一身本领,霸气外露。如今来到了和之国,正和小伙伴一起讨伐凯多。这个时候,讨伐凯多(和之国篇)就是海贼王世界中的一个进程,它的地址空间是凯多大本营——和之国。【python学习】从海贼王中体会进程、线程和协程 那要如何才能灭了凯多呢?讨伐大军需要先混入敌军地盘,接着潜伏收集情报,然后密谋计划,最后杀入敌营斩下凯多首级,这些属于整个讨伐进程的子进程。讨伐大军是怎么获取的情报,敌人老窝是怎么潜入的,路飞是怎么打的,佐罗是怎么砍的。。。这些就属于进程代码段的内容。凯多也不是吃素的,起飞鬼岛砸向花之都,鬼岛的飞行时间应该就是整个剧情高潮时间,是一个全局变量,属于进程数据段内容。这边草帽一伙打得火热,世界政府、海军、革命军也没闲着,虽然作者没有交代,但也在海贼世界中进行着,这些就构成了海贼王里的多进程【python学习】从海贼王中体会进程、线程和协程

python中的进程模块multiprocessing多进程举例

# 进程代码
import os
from multiprocessing import Process


def fun_1(str):
    print("海贼王子进程id:", os.getpid(), str)


def main():
    p1 = Process(target=fun_1, args=('进程1:讨伐凯多',))
    p2 = Process(target=fun_1, args=('进程2:革命军在搞事',))
    p3 = Process(target=fun_1, args=('进程3:世界政府在观察',))

    p1.start()
    p2.start()
    p3.start()
    print('海贼王主进程id:', {os.getpid()})


if __name__ == '__main__':
    main()

输出结果(每次运行结果不同): 【python学习】从海贼王中体会进程、线程和协程

2 线程

线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

线程是在进程下执行的,并共享上下文,因此同一个进程下的线程间通信更加容易。子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。所以子程序调用是通过栈实现的,一个线程就是执行一个子程序。子程序调用总是一个入口,一次返回,调用顺序是明确的。而协程的调用和子程序不同。

好 ,现在继续我们的海贼之旅。

要灭了凯多可不是一件容易的事,凯多方人多势众,还和大妈结盟,战力杠杠。那怎么搞定他们呢?所有人聚在一起刚正面,那估计路飞还没碰到凯多就累死了,所以为了尽快实现目的,每个角色都找到了自己的对手,王对王、将对将、兵对兵,大家分别PK。路飞、佐罗几人挑凯多和大妈;马尔科vs烬和奎因;甚平vs福斯福;弗兰克vs佐佐木。。。每一场战斗都是讨伐凯多进程当中的线程,分别执行,互不干扰,可以认为是并发【python学习】从海贼王中体会进程、线程和协程 另外,在海贼王中还有一个角色具有多线程的特性,就是“匪帮”卡彭·贝基,他的坚城果实能力,直接让其可以轻松以一敌百。 【python学习】从海贼王中体会进程、线程和协程

python中多线程代码举例

import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print ("开始线程:" + self.name)
        print_time(self.name, self.counter, 5)
        print ("退出线程:" + self.name)

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            threadName.exit()
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

if __name__ == "__main__":
    # 创建新线程
    thread1 = myThread(1, "线程1-路飞vs凯多", 1)
    thread2 = myThread(2, "线程2-甚平vs福斯福", 2)

    # 开启新线程
    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()
    print ("退出讨伐凯多主线程")

输出结果为: 【python学习】从海贼王中体会进程、线程和协程

3 协程

协程 (coroutine),又称为微线程,它是实现多任务的另一种方式,只不过是比线程更小的执行单元。因为它自带CPU的上下文,这样只要在合适的时机,我们可以把一个协程切换到另一个协程。

在一个线程中的某个函数中,我们可以在任何地方保存当前函数的一些临时变量等信息,然后切换到另外一个函数中执行,注意不是通过调用函数的方式做到的,并且切换的次数以及什么时候再切换到原来的函数都由开发者自己确定。

终于,到我们的真男人-山治出来秀一波了。

西服、香烟的标配,这就是我们的绅士-山治,凭一双脚踢出一个世界的男人。不过在和之国篇中变现还不出彩,在面对黑玛丽亚的时候发生中断无法施展自己的实力,山治只能向罗宾发出求救信号。罗宾这边一收到信号,就yield知道了。整个过程都是山治在执行求救信号,直到信号次数达到一个阀值,罗宾出现了。 【python学习】从海贼王中体会进程、线程和协程

python中协程代码理解

def luobin():
    r = ''
    while True:
        n = yield r
        if not n:
            return
        if n == 5:
            print("[罗宾] 我听到第 %s 次求救了,我到了" % n)
        else:
            print('[罗宾] 我听到第 %s 次求救了,马上来' % n)
            r = '知道了,马上'

def shanzhi(c):
    c.send(None)
    n = 0
    while n < 5:
        n = n + 1
        print('[山治] 第 %s 次求救:罗宾快来救我' % n)
        r = c.send(n)
        if n == 5:
            print('[山治] 罗宾你来了!')
        else:
            print('[山治] 罗宾回答: %s' % r)
    c.close()

c = luobin()
shanzhi(c)

输出结果为:

[山治] 第 1 次求救:罗宾快来救我
[罗宾] 我听到第 1 次求救了,马上来
[山治] 罗宾回答: 知道了,马上
[山治] 第 2 次求救:罗宾快来救我
[罗宾] 我听到第 2 次求救了,马上来
[山治] 罗宾回答: 知道了,马上
[山治] 第 3 次求救:罗宾快来救我
[罗宾] 我听到第 3 次求救了,马上来
[山治] 罗宾回答: 知道了,马上
[山治] 第 4 次求救:罗宾快来救我
[罗宾] 我听到第 4 次求救了,马上来
[山治] 罗宾回答: 知道了,马上
[山治] 第 5 次求救:罗宾快来救我
[罗宾] 我听到第 5 次求救了,我到了
[山治] 罗宾你来了!

4 结尾

基础内容看似简单,想要精通也得花不少精力。记录下该文,望日后翻阅,能有醍醐灌顶之功效,哈哈。

更多内容,欢迎关注公众号:Python生活志

点赞
收藏
评论区
推荐文章
浅梦一笑 浅梦一笑
4个月前
初学 Python 需要安装哪些软件?超级实用,小白必看!
编程这个东西是真的奇妙。对于懂得的人来说,会觉得这个工具是多么的好用、有趣,而对于小白来说,就如同大山一样。其实这个都可以理解,大家都是这样过来的。那么接下来就说一下python相关的东西吧,并说一下我对编程的理解。本人也是小白一名,如有不对的地方,还请各位大神指出01名词解释:如果在编程方面接触的比较少,那么对于软件这一块,有几个名词一定要了解,比如开发环
Jacquelyn38 Jacquelyn38
1年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Stella981 Stella981
1年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Stella981 Stella981
1年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Wesley13 Wesley13
1年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
1年前
MySQL查询按照指定规则排序
1.按照指定(单个)字段排序selectfromtable_nameorderiddesc;2.按照指定(多个)字段排序selectfromtable_nameorderiddesc,statusdesc;3.按照指定字段和规则排序selec
Stella981 Stella981
1年前
Angular material mat
IconIconNamematiconcode_add\_comment_addcommenticon<maticonadd\_comment</maticon_attach\_file_attachfileicon<maticonattach\_file</maticon_attach\
Wesley13 Wesley13
1年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
helloworld_34035044 helloworld_34035044
6个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
二进制打工人
二进制打工人
Lv1
出师未捷身先死,长使英雄泪满襟。
1
文章
0
粉丝
1
获赞
热门文章

暂无数据