Python 进程概述 进程方法与全局变量的访问

生活中,你可以一边听歌,一边写作业,一边上网,一边吃饭……这些都是生活中多任务场景。电脑也可以执行多任务。比如你可以同时打开浏览器上网,听音乐啊等等。

并发和并行

并发:当有多个线程在操作时,如果系统只有一个CPU,则他根本不可能真正的同时进行一个以上的线程,它只能吧CPU运行时间划分为若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其他线程处于挂起状,这种方式我们称之为并发。
并行:当系统有一个以上CPU时,则线程的的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们能称之为并行。

– 多进程模式
– 多线程模式
– 协程
– 进程>线程>协程

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及组织形式的描述,进程是程序的实体。
对于操作系统来说,一个任务就是一个进程。比方说打开浏览器就是启动一个浏览器的进程,在打开一个记事本就是启动一个记事本的进程,如果打开两个记事本就是启动两个记事本的进程。

优点

  • 稳定性高,一个进程崩溃了,不会影响其他进程。

缺点

  • 城建进程开销大;
  • 操作系统能同时运行进程数目有限。

启动任务管理器查看进程
Linux和Unix操作系统提供了一个fork()函数创建新的进程,这也就意味着该函数仅适用于Linux和Unix平台。
fork()函数比较特殊,python的os.fork()是唯一调用返回两次的函数,因操作系统将当前的进程(父进程)复制了一份新的进程(子进程),然后分别在父进程和子进程内返回。
例如:采用父进程拷贝文件,子进程的拷贝并不是从开始就行的(除非进行设置),混乱拷贝文件可能出现结果异常而出现错误。
注意:有时在一个终端会混合出现打印结果。
fork()从本质上属于内建函数,通过os模块导入。
下面linux代码

import os
pid = os.fork()

if pid<0:
    print("creat process failed")
elif pid == 0:
    print("this is child process")
else:
    print("this is parent process")

print("*******this end*******")

python代码
程序1


#进程创建
from multiprocessing import Process
from time import sleep
def task1():
    while True:
        sleep(1)
        print('这是任务一...........')

def task2():
    while True:
        sleep(1)
        print('这是任务二...........')

if __name__ == '__main__':
    p1 = Process(target=task1,name='任务1')
    p1.start()  #start()是开进程做这个动作,run是直接做这个动作
    print(p1.name)
    p2 = Process(target=task2,name='任务2')
    p2.start()
    print(p2.name)

结果1

任务1
任务2
这是任务一...........
这是任务二...........
这是任务一...........
这是任务二...........
这是任务一...........
这是任务二...........
这是任务一...........

结果分析;一直在运行

程序2

#进程创建
from multiprocessing import Process
from time import sleep
def task1():
    while True:
        sleep(1)
        print('这是任务一...........')

def task2():
    while True:
        sleep(1)
        print('这是任务二...........')

if __name__ == '__main__':
    #子进程
    p1 = Process(target=task1,name='任务1')
    p1.start()  #start()是开进程做这个动作,run是直接做这个动作
    print(p1.name)
    p2 = Process(target=task2,name='任务2')
    p2.start()
    print(p2.name)

    print('---------')
    print('************************')

结果2

任务1
任务2
---------
************************
这是任务一...........
这是任务二...........
这是任务一...........
这是任务二...........
这是任务一...........
这是任务二...........
这是任务一...........

结果分析:(任务1任务2---------************************ )主进程运行完了,在进行子进程运行 (这是任务一…这是任务二…这是任务一…)
进程描述
程序2

#进程创建
import os
from multiprocessing import Process
from time import sleep
def task1():
    while True:
        sleep(1)
        print('这是任务一...........',os.getpid(),'-------',os.getppid())

def task2():
    while True:
        sleep(1)
        print('这是任务二...........',os.getpid(),'-------',os.getppid())

if __name__ == '__main__':
    print(os.getpid())
    print(os.getppid())
    #子进程
    p1 = Process(target=task1,name='任务1')
    p1.start()  #start()是开进程做这个动作,run是直接做这个动作
    print(p1.name)
    p2 = Process(target=task2,name='任务2')
    p2.start()
    print(p2.name)

    print('---------')
    print('************************')

结果2

8540
7864
任务1
任务2
---------
************************
这是任务一........... 7404 ------- 8540
这是任务二........... 10084 ------- 8540
这是任务一........... 7404 ------- 8540
这是任务二........... 10084 ------- 8540

结果分析:我们可以通过os.getpid()获得进程号
程序3

#进程创建
import os
from multiprocessing import Process
from time import sleep
def task1(s):
    while True:
        sleep(s)
        print('这是任务一...........',os.getpid(),'-------',os.getppid())

def task2(s):
    while True:
        sleep(s)
        print('这是任务二...........',os.getpid(),'-------',os.getppid())

if __name__ == '__main__':
    print(os.getpid())
    print(os.getppid())
    #子进程
    p1 = Process(target=task1,name='任务1',args=(1,))
    p1.start()  #start()是开进程做这个动作,run是直接做这个动作
    print(p1.name)
    p2 = Process(target=task2,name='任务2',args=(2,))
    p2.start()
    print(p2.name)

    print('---------')
    print('************************')

结果3

14940
7864
任务1
任务2
---------
************************
这是任务一........... 9904 ------- 14940
这是任务二........... 14552 ------- 14940
这是任务一........... 9904 ------- 14940
这是任务一........... 9904 ------- 14940
这是任务二........... 14552 ------- 14940
这是任务一........... 9904 ------- 14940
这是任务一........... 9904 ------- 14940
这是任务二........... 14552 ------- 14940
这是任务一........... 9904 ------- 14940

结果分析:我们将task2(s),设置变量s,利用进程的属性 p2 = Process(target=task2,name=‘任务2’,args=(2,)),设置s时间秒数。()是元组,可迭代的,因此可以再放入两个或多个参数。

程序4

import os
from multiprocessing import Process
from time import sleep
def task1(s,name):
    while True:
        sleep(s)
        print('这是任务一...........',os.getpid(),'-------',os.getppid(),name)

def task2(s,name):
    while True:
        sleep(s)
        print('这是任务二...........',os.getpid(),'-------',os.getppid(),name)

if __name__ == '__main__':
    print(os.getpid())
    print(os.getppid())
    #子进程
    p1 = Process(target=task1,name='任务1',args=(1,'aa'))
    p1.start()  #start()是开进程做这个动作,run是直接做这个动作
    print(p1.name)
    p2 = Process(target=task2,name='任务2',args=(2,'bb'))
    p2.start()
    print(p2.name)

    print('---------')
    print('************************')

结果4

14496
7864
任务1
任务2
---------
************************
这是任务一........... 11512 ------- 14496 aa
这是任务一........... 11512 ------- 14496 aa
这是任务二........... 1856 ------- 14496 bb
这是任务一........... 11512 ------- 14496 aa
这是任务二........... 1856 ------- 14496 bb

总结

from multiprocessing import Process
Process(target =函数,name=进程的名字,args = (给函数传递的参数))
process对象

对象调用方法:
process.start()启动进程并执行任务
process.run() 只是执行了任务,但是没有启动进程
terminate() 终止

举例:terminate()终止进程
程序5

import os
from multiprocessing import Process
from time import sleep
def task1(s,name):
    while True:
        sleep(s)
        print('这是任务一...........',os.getpid(),'-------',os.getppid(),name)

def task2(s,name):
    while True:
        sleep(s)
        print('这是任务二...........',os.getpid(),'-------',os.getppid(),name)

number = 1
if __name__ == '__main__':
    print(os.getpid())
    print(os.getppid())
    #子进程
    p1 = Process(target=task1,name='任务1',args=(1,'aa'))
    p1.start()  #start()是开进程做这个动作,run是直接做这个动作
    print(p1.name)
    p2 = Process(target=task2,name='任务2',args=(2,'bb'))
    p2.start()
    print(p2.name)

    while True:
        number += 1
        sleep(0.2)
        if number == 20:
            p1.terminate()
            p2.terminate()
            break
        else:
            print('---------number:',number)
    print('---------')
    print('************************')

结果5

13964
7864
任务1
任务2
---------number: 2
---------number: 3
---------number: 4
---------number: 5
---------number: 6
这是任务一........... 14508 ------- 13964 aa
---------number: 7
---------number: 8
---------number: 9
---------number: 10
---------number: 11
这是任务一........... 14508 -------这是任务二...........  13964 4488 aa-------
 13964 bb
---------number: 12
---------number: 13
---------number: 14
---------number: 15
---------number: 16
这是任务一........... 14508 ------- 13964 aa
---------number: 17
---------number: 18
---------number: 19
---------
************************

Process finished with exit code 0

结果分析:当number == 20时,终止进程。

下面我么你分析全局变量的访问
全局变量的访问
程序6

import os
from multiprocessing import Process
from time import sleep
m = 1#全局变量
def task1(s,name):
    global m    #对全局变量进行修改,需要声明global
    while True:
        sleep(s)
        m += 1
        print('这是任务一...........',m)

def task2(s,name):
    global m    #对全局变量进行修改,需要声明global
    while True:
        sleep(s)
        m += 1
        print('这是任务二...........',m)

number = 1
if __name__ == '__main__':
    print(os.getpid())
    print(os.getppid())
    #子进程
    p1 = Process(target=task1,name='任务1',args=(1,'aa'))
    p1.start()  #start()是开进程做这个动作,run是直接做这个动作
    print(p1.name)
    p2 = Process(target=task2,name='任务2',args=(2,'bb'))
    p2.start()
    print(p2.name)

结果6

2288
7864
任务1
任务2
这是任务一........... 2
这是任务一........... 3
这是任务二........... 2
这是任务一........... 4
这是任务一........... 5
这是任务二........... 3
这是任务一........... 6
这是任务一........... 7
这是任务二........... 4
这是任务一........... 8
这是任务一........... 9
这是任务二........... 5
这是任务一........... 10
这是任务一........... 11
这是任务二........... 6
这是任务一........... 12
这是任务一........... 13
这是任务二........... 7
这是任务一........... 14
这是任务一........... 15
这是任务二........... 8

结果分析:m这个变量,放在全局变量里面,就相当于子进程自己也拥有了各自的m。
分析
程序7

import os
from multiprocessing import Process
from time import sleep
m = 1#全局变量
def task1(s,name):
    global m    #对全局变量进行修改,需要声明global
    while True:
        sleep(s)
        m += 1
        print('这是任务一...........',m)

def task2(s,name):
    global m    #对全局变量进行修改,需要声明global
    while True:
        sleep(s)
        m += 1
        print('这是任务二...........',m)

number = 1
if __name__ == '__main__':
    print(os.getpid())
    print(os.getppid())
    #子进程
    p1 = Process(target=task1,name='任务1',args=(1,'aa'))
    p1.start()  #start()是开进程做这个动作,run是直接做这个动作

    p2 = Process(target=task2,name='任务2',args=(2,'bb'))
    p2.start()

    while True:
        sleep(1)
        m += 1
        print('------->main:',m)

结果7

15280
7864
------->main: 2
这是任务一........... 2
------->main: 3
这是任务一........... 3
这是任务二........... 2
------->main: 4
这是任务一........... 4
------->main: 5
这是任务一........... 5
这是任务二........... 3
------->main: 6
这是任务一........... 6
------->main: 7
这是任务一........... 7
这是任务二........... 4
------->main: 8
这是任务一........... 8
------->main: 9
这是任务一........... 9
这是任务二........... 5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值