python学习---进程和线程(1)进程

多应用任务

def func1(n):
    for i in range(n):
        print('搬砖',i)
        yield None

def func2(n):
    for i in range(n):
        print('听歌',i)
        yield None

g1 = func1(3)
g2 = func2(3)

while True:
    try:
        g1.__next__()
        g2.__next__()
    except:
        break

线程和进程

并发和并行

  • 并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。
  • 并发:CPU运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。
  • 并行:当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行

实现多任务的方式

  • 多进程
  • 多线程
  • 协程
  • 进程>线程>协程

进程

创建进程

  • 首先导入Process

    from multiprocessing import Process

  • Process(target=函数,name=进程的名字,args=(向函数传递的参数,可迭代的对象))

  • 对于进程对象process

    • process.start()执行任务并启动进程

    • process.run()执行任务但不启动进程

    • process.terminate()终止

from multiprocessing import Process
from time import sleep
import os

def task1(s,name):
    while True:
        sleep(s)
        print('task1``````````````',os.getpid(),'·······················',os.getppid(),name)
def task2(s,name):
    while True:
        sleep(s)
        print('task2````````````````',os.getpid(),'··················',os.getppid(),name)

if __name__ == '__main__':
    p1 = Process(target=task1,name='rw1',args=(1,'aa'))#子进程
    p1.start()
    print(p1.name)#主进程所做的
    p2 = Process(target=task2,name='ew2',args=(2,'bb'))# 子进程
    p2.start()
    print(p2.name)
    n = 1
    while True:
        n+=1
        sleep(0.2)
        if n == 5:
            p1.terminate()
            print('p1 stop')
            break
        else:
            print(n)
  • 多进程对于全局变量访问,在每一个全局变量里都放一个m变量 保证每个进程访问变量互相不干扰
  • 对于不可变的变量还是可变变量都是一样的效果
from multiprocessing import Process
from time import sleep

m=0 #不可变类型
list1=[] #可变类型
def task1():
    while True:
        sleep(1)
        global  m
        m+= 1
        list1.append(str(m)+'t1')
        print('task1``````````````',m,list1)
def task2():
    while True:
        sleep(2)
        global  m
        m+= 1
        list1.append(str(m) + 't2')
        print('task2````````````````',m,list1)

if __name__ == '__main__':
    p1 = Process(target=task1,name='rw1')
    p1.start()
    p2 = Process(target=task2,name='ew2')
    p2.start()
    while True:
        sleep(1)
        m+=1
        print('main:',m)

自定义进程

继承Process类,并根据需求重写方法

from multiprocessing import Process
class MyProcess(Process):
    #重写run方法
    def __init__(self,name):
        super(MyProcess,self).__init__()
        self.name=name
    def run(self) :
        n=1
        while True:
           # print('进程名:',self.name)
            print('---------------->自定义进程,n=',n,self.name)
            n+=1
if __name__ == '__main__':
    p = MyProcess('xiaom')
    p.start()

进程池

  • 可以自己设置进程数。
  • 可以复用。任务数>池中位置数,当一个任务结束后,会自动加入一个新的任务。
  • pool=Pool(n)创建进程池
  • pool.close()任务添加结束
  • pool.join()插队,让主进程给自己让路
阻塞式

使用apply()一个一个来,一个一个的完成,一个一个的返回。一个不完成,另一个不加入。没有回调函数

from multiprocessing import Pool
import time
import random
import os
def task(name):
    print('start:',name)
    st= time.time()
    time.sleep(random.random())
    end = time.time()
    print('work:{},time:{},id:{}'.format(name,(end-st),os.getpid()))
  #  return 'work:{},time:{},id:{}'.format(name,(end-st),os.getpid())

container = []
def callback_func(n):
    container.append(n)

if __name__ == '__main__':
    pool=Pool(3)
    tasks = ['game','movie','sleep','keep','work']
    for t in tasks:
        pool.apply(task,args=(t,))

    pool.close()#任务添加结束
    pool.join()#插队

    for c in container:
        print('callback:',c)
    print('over')
"""
start: game
work:game,time:0.2110910415649414,id:13040
start: movie
work:movie,time:0.9919724464416504,id:11200
start: sleep
work:sleep,time:0.04570508003234863,id:3120
start: keep
work:keep,time:0.9166526794433594,id:13040
start: work
work:work,time:0.26379990577697754,id:11200
over
"""
非阻塞式

使用apply_async()全部添加到队列,立刻返回,并没有等待其他进程完毕,回调函数等待全部任务完成后才调用。

from multiprocessing import Pool
import time
import random
import os
def task(name):
    print('start:',name)
    st= time.time()
    time.sleep(random.random())
    end = time.time()
    return 'work:{},time:{},id:{}'.format(name,(end-st),os.getpid())

container = []
def callback_func(n):
    container.append(n)

if __name__ == '__main__':
    pool=Pool(3)
    tasks = ['game','movie','sleep','keep','work']
    for task1 in tasks:
        pool.apply_async(task,args=(task1,),callback=callback_func)

    pool.close()#任务添加结束
    pool.join()#插队

    for c in container:
        print('callback:',c)
    print('over')
"""
start: game
start: movie
start: sleep
start: keep
start: work
callback: work:sleep,time:0.168532133102417,id:19648
callback: work:keep,time:0.45188164710998535,id:19648
callback: work:game,time:0.712028980255127,id:11288
callback: work:movie,time:0.8986353874206543,id:15052
callback: work:work,time:0.8844568729400635,id:19648
over
"""

进程间的通信

使用Queue

  • q = Queue(n) 创建长度为n的队列
  • full() 判断队列是否满了
  • empty() 判断是否空
  • put() 向队列中添加值,如果queue满了就只能等待,除非有空地才能添加成功
  • get() 在队列中取值,如果空了就等待
from multiprocessing import Queue
q = Queue(3)
q.put('1')
q.put('2')
q.put('3')
print(q.qsize())

if not q.full():
    q.put('4', timeout=2)  
else:
    print('full')
print(q.get(timeout=1))
print(q.get(timeout=1))
print(q.get(timeout=1))

if not q.empty():
    print(q.get(timeout=1))
else:
    print('empty')
"""
3
full
1
2
3
empty

"""

进程中的通信通过传值进行

from multiprocessing import Process
from multiprocessing import Queue
from time import sleep
def download(q):
    img = ['a.jpg','b.jpg','c.jpg']
    for i in img:
        print('downloading:',i)
        sleep(0.5)
        q.put(i)
def grtfile(q):
    while True:
        try:
            file = q.get()
            print('finish:',file)
        except:
            print('done')
            break

if __name__ == '__main__':
    q = Queue(3)
    p1 =  Process(target=download,args=(q,))
    p2 = Process(target=grtfile,args=(q,))
    p1.start()
    p1.join()
    p2.start()
    p2.join()
"""
downloading: a.jpg
downloading: b.jpg
downloading: c.jpg
finish: a.jpg
finish: b.jpg
finish: c.jpg

Process finished with exit code -1
"""
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值