Discuss / Python / 进程线程这一大章的内容终于全部懂了

进程线程这一大章的内容终于全部懂了

Topic source

最开始看这一节的时候真的是一脸蒙蔽。。。估计很多人开始也是这样。。

但现在突然觉得挺简单的,回头来写点自己的理解:

**保证在座的各位都能看懂的版本!**↓↓


先说两句:什么是进程?有什么用?——ok,那我问你,你能一手画圆一手画方吗?——我猜不能。但计算机就不一样了,一边绘制正方体一边绘制球体都是小case(屏幕上自动绘制图形),这是因为计算机启动了另一个"大脑"来处理另一个任务,即两个“大脑”分别同时画两个图形 效率X2!我们之前的写程序都是计算机一个“大脑”在工作!ok,那怎么启动计算机其他的大脑呢?——启动另一个进程就可以了!


1、创建进程:(直接复制粘贴运行对照输出。。)

import multiprocessing
import time

def action(a, b):  # 待会两个进程要执行的任务↓
    for i in range(30):  # 循环30次
        print(a, ' ', b)
        time.sleep(0.1)  # 等待0.1s

if __name__ == '__main__':  # 这行代码很重要,新建进程的时候都加上它!!原因不用管(我也不知道233)

    jc1 = multiprocessing.Process(target=action, args=('进程一', 0))  # 准备建立一个进程:multiprocessing.Process()
    jc2 = multiprocessing.Process(target=action, args=('进程二', 1))  # 再准备建立一个新进程,这是基本格式记住←
# 必要参数target:指定进程要执行的任务(这里是执行函数 action),必要参数args:直译成中文就是'参数',顾名思义就是前面target的参数,即action的参数,注意args是个元组,所以args后的参数写成tuple元组格式。直接写target('进程一',0)一定报错的

    jc1.start()  # 将蓄势待发的jc1进程正式启动!!
    jc2.start()  # 同上...

    jc1.join()  # 等待进程jc1将任务执行完...
    jc2.join()  # ...
    print('jc1,jc2任务都已执行完毕')

    jc1.close()  # 彻底关闭进程jc1
    jc2.close()  # ...

     #输出结果是两个进程同时且连续打印0、1


2、Pool:(直接复制粘贴运行对照输出。。)

import time
import os

def action1(a, b=50):
    for i in range(b):
        print(a, os.getpid(), ' ', i)  # os.getpid(): pid简单来说就是每个进程的“身份证”
        time.sleep(0.1)

if __name__ == '__main__':  # 还要添加这行,否则可能出现异常

    ci = Pool(3)  # 创建一个进程池,容量为3个进程
    ci.apply_async(action1, args=('进程一',))  # 启动第一个子进程...
    ci.apply_async(action1, args=('进程二', 50))  # 和普通进程的启动方式有很大不同仔细看
    ci.apply_async(action1, args=('进程三', 60))  # Pool的最基本格式记住←
# 注意:程序现在有4个进程在运行:上面的三个子进程 和一个最为核心的:主进程

    ci.close()  # 关闭进程池(但池子内已启动的子进程还会继续进行)
    ci.join()  # 等待进程池内的所有子进程完毕
    print('比如说这最后的一行输出就是主进程执行任务打印出来的')

    #主进程(父进程)全程干了什么?创建进程池、启动子进程、关闭进程池、等待子进程完毕、打印最后一行


3、进程间的通信::(直接复制粘贴运行对照输出。。)

import multiprocessing

def foo(aa):
    ss = aa.get()  # 管子的另一端放在子进程这里,子进程接收到了数据
    print('子进程已收到数据...')
    print(ss)  # 子进程打印出了数据内容...

if __name__ == '__main__':  # 要加这行...

    tx = multiprocessing.Queue()  # 创建进程通信的Queue,你可以理解为我拿了个管子来...
    jc = multiprocessing.Process(target=foo, args=(tx,))  # 创建子进程
    jc.start()  # 启子子进程

    print('主进程准备发送数据...')
    tx.put('有内鬼,终止交易!')  # 将管子的一端放在主进程这里,主进程往管子里丢入数据↑
    jc.join()

    #这种方法可以实现任意进程间的通信,这里写的是主、子进程间的通信


OK!哈哈  睡觉觉(¦3[▓▓] 晚安

注释里有个笔误。不过不碍事。。ok

Leonardo_6666

#3 Created at ... [Delete] [Delete and Lock User]

搞不懂”1、创建进程”中为啥是先join( )再close( )的,跟廖老师说的反了。我先进程close( )再join( )反而报错。

Leonardo_6666

#4 Created at ... [Delete] [Delete and Lock User]

哦哦廖老师是说调用Pool模块时先join( )再close( )。直接创建多进程,join( )是必要的,close( )有没有无所谓。

Leonardo_6666

#5 Created at ... [Delete] [Delete and Lock User]

“3、进程间的通信”得到的输出是

子进程已收到数据...
有内鬼,终止交易!
主进程准备发送数据...

为啥“有内鬼,终止交易!”在“主进程准备发送数据...”之前呢?明明代码是先print再put。

我运行的时候↓

子主进程准备发送数据...
进程已收到数据...
有内鬼,终止交易!

你多运行几次估计会有正常顺序输出的时候。。

或者在 def foo(aa): 一行下面加一句 time.sleep(0.1) 就绝对正常了。。

是我代码太烂了。。。

电脑配置不同有所差异很正常。

因为print语句执行的时间太长了。。。

Python中执行print语句的时间和计算2**3000所用的时间居然是差不多的!!

为了加快python程序运行,在print语句未执行完毕的时候其实就已经开始执行下一句了

说简单点就是说我代码不严谨。。

Normaloo

#7 Created at ... [Delete] [Delete and Lock User]

    print('主进程准备发送数据...')

    tx.put('有内鬼,终止交易!') 

    jc.start()  # 启子子进程

    jc.join()

保证put在get之前运行

凡水齐民

#8 Created at ... [Delete] [Delete and Lock User]

懂了!谢谢

if __name__ == '__main__':

知乎上的回答:编写私有化部分 ,这句代码以上的部分,可以被其它的调用,以下的部分只有这个文件自己可以看见,如果文件被调用了,其他人是无法看见私有化部分的*  。*

也就是说你自己运行该模块的时候 这句话是执行的 因为自己运行时__name__就是__main__,而当别人调用你这个模块时,以下代码会被忽略,此时的__name__是模块名

only才子_742

#10 Created at ... [Delete] [Delete and Lock User]

进程和线程留眼复习。。。。。


Reply