Python实现多进程、多线程以及多协程任务

一、python实现多进程

1.1 多进程函数实现多任务

第一步:导入multiprocessing;

第二步:定义一个函数;

第三步:进程对象使用multiprocessing.Process();

第四步:进程对象.start()正式创建进程

第五步:主进程继续向下运行代码

from multiprocessing import Process
import time


def task():
    count_0 = 0
    while count_0 < 11:
        count_0 += 1
        print("我是子进程")
        time.sleep(1)

if __name__=="__main__":
    
    p = Process(target=task)
    p.start()

    count_1 = 0
    while count_1<11:
        count_1 += 1
        print("我是主进程")
        time.sleep(1)

1.2 多进程类实现多任务

from collections.abc import Callable, Iterable, Mapping
from multiprocessing import Process
import time
from typing import Any

class Mulprocess(Process):
    #def __init__(self):
        #super().__init__()
        
    def run(self):
        count = 0
        while count < 11:
            count += 1
            print("我是程咬金")
            time.sleep(0.5)

if __name__ == "__main__":
    p = Mulprocess()
    p.start()
    count0 = 0
    while count0 < 11:
        count0 += 1
        print("我是渣渣灰")
        time.sleep(0.5)

1.3 进程之间的通信

from multiprocessing import Queue

q = Queue(3)
q.put("new1")
q.put("new2")
print(q.full())
q.put("new3")
print(q.full())

try:
     q.put("news4",timeout=2)
except:
     print("消息队列已满,现有消息数量{}".format(q.qsize()))

try:
     q.put_nowait("new4")
except:
     print("消息对列已满,现有消息{}".format(q.qsize()))
if not q.full():
     q.put_nowait("new4")
if not q.empty():
     for i in range(q.qsize()):
          print(q.get_nowait())

1.4 通过Quene实现多进程之间的通信

from multiprocessing import Process
from multiprocessing import Queue
import time

def task1(q):
    items = ["a","b","c","d"]
    for i in items: 
        q.put(i)
        print(i)

def task2(q):
    while not q.empty():
        value = q.get_nowait()
        print("提取出来的数据是{}".format(value))
       

if __name__ == "__main__":
    q = Queue()
    t1 = Process(target=task1,args=(q,))
    t2 = Process(target=task2,args=(q,))
    t1.start()
    t2.start()

#进程之间是独立的,所有的数据都是各自使用,为了实现进程之间可以进行数据共享,
#不能使用全局变量,可以使用Linux(Unix)给出的解决方案
#1、进程之间通信(IPC)
#1.1 管道
#1.2 命名管道
#1.3 socket(重点):能够实现多台电脑上进程之间的通讯
#。。。。。。
#2、为了更加简单的实现进程之间的通讯,可以使用Queue

1.5 关于Quene介绍

import queue

#对列
#1、先进先出(FIFO:first in first out)
#2、可以存储不同的数据类型,例如整数,字符串,类型
#3、使用put放数据
#4、使用get取数据
q = queue.Queue()
q.put("11")
q.put(22)
q.put({"num":33})

print(q.get())
print(q.get())
print(q.get())

#堆栈
#1、先进后出(LIFO:last in first out)
#2、可以存储不同的数据类型,例如整数,字符串,类型
#3、使用put放数据
#4、使用get取数据
ql = queue.LifoQueue()
ql.put("11")
ql.put(22)
ql.put({"num":33})
print(ql.get())
print(ql.get())
print(ql.get())


#优先级Queue
#1、存放的数据是元组类型,第一个元素表示优先级,第二个元素表示存储的数据
#2、优先级数字越小优先级越高
#3、数据优先级高的优先取出
#4、用于VIP用户的数据优先被取出场景,因为上面两种都要挨个取出来
qp = queue.PriorityQueue()
qp.put((10,'a'))
qp.put((20,'k'))
qp.put((30,'v'))
print(qp.get())
print(qp.get())
print(qp.get())

1.6 创建进程池

#为什么使用进程池?
#当需要创建的子进程数量不多时,可以直接利用multiprocess中的Process动态生成多个进程,
#但是如果是上百甚至上千个目标,手动去创建进程的工作就会比较大,此时可以使用multiprocess中的Pool方法

from multiprocessing import Pool
import time
import os
import random

def task(num):
    print('==num={}'.format(num))
    time.sleep(1)

#表示进程池中最多只有三个进程同时执行
if __name__ == '__main__':
    pool = Pool(2)

    for i in range(10):
        print('-------{}------------'.format(i))
        #想进程中添加任务
        #注意:如果添加的任务数量超过了进程池中进程的数量,那么就不会接着往进程池中添加
        #      如果还没有执行,他会等待前面的进程结束,然后往进程池中添加新的进程
        pool.apply_async(task,(i,))
    print("-------主进程添加任务结束-------")
    pool.close()  #关闭进程池
    pool.join()   #主进程在这里等待,只有子进程全部结束之后才会结束主线程

二、 python实现多线程

2.1 创建对象并传递参数

import threading
import time

def task5(num):
    for i in range(num):
        print("老子真帅")


def work(num1,num2,num3,n):
    print("------in work----num1={},num2={}.num3={},n={}".format(num1,num2,num3,n))

t3 = threading.Thread(target=work,args=(1,2),kwargs={"n":4,"num3":3})
t3.start()

print(threading.enumerate())
t = threading.Thread(target=task5,args=(3,))
t.start()
print(threading.enumerate())

2.2 多线程函数实现多任务

#导入threading模块
import threading
import time 

def task1():
    while True:
        print("111111")
        time.sleep(1)
#使用threading模块中的Tread创建一个对象
def task2():
    while True:
        print("33333333333")
        time.sleep(1)

t1 = threading.Thread(target = task1)
t2 = threading.Thread(target = task2)

#调用这个实例对象的start方法让这个线程开始运行
t1.start()
t2.start()

while True:
    print("22222222222")
    time.sleep(1)



#1、想要执行一个单独的任务就需要创建一个新的线程。
#2、在python中使用threading模块中的Thread类,就可以创建一个对象,这个对象标记一个线程,创建出来的线程默认是不会执行的
#3、调用这个线程对象的start方法,就可以让这个新的线程开始执行代码,要看在用Thread创建对象的时候target参数传递的是哪个函数的引用,即将来线程就会执行target参数指定的那个函数
#4、如果在一个程序中想要多个程序一起运行,则需要创建多个线程。


#多线程程序运行的先后顺序是不确定的,因为在代码执行的时候,当前的运行环境可能不同,会导致操作系统在计算机接下来的应该调用那个程序的时候,因此顺序不确定

2.3 多线程类实现多任务

import threading
import time

class Task(threading.Thread):
    def run(self):
        count = 0
        while count <11:
            count += 1
            print("11111111111111")   
            time.sleep(1)

t = Task()
t.start()

count1 = 0
while count1 < 12:
    count1 += 1
    print("main")
    time.sleep(1)


#1、可以自己定义一个类来继承Thread
#2、一定要实现run方法,即要定义一个run 方法,并且实现线程需要定义线程需要执行的代码
#3、当调用自己编写的类创建出来的实例对象方法run时,会创建新的线程,并且线程会调用run方法
#4、如果除了run方法之外还定义了很多其他的方法,那么这些方法需要在run方法中自己去调用,线程不会直接调用

2.4 互斥锁

import threading

mutex = threading.Lock()

mutex.acquire()

print("哈哈哈哈")

mutex.release()
#如果这个互斥锁已经上锁了,在这个互斥锁解开之前是不能上锁的,
#也就是说:如果这锁被锁上 在解开之前谁要是再次调用acquire对其上锁,谁就会被堵塞。
#注意:一定要是同一把锁才可以 

2.5 互斥锁实例

import threading

mutex = threading.Lock()
#global num_gob
num_gob = 0

def task1(num):
    global num_gob
    for i in range(num):
        #mutex.acquire()
        num_gob += 1
        #mutex.release()
    print(num_gob)

def task2(num):
    global num_gob
    for i in range(num):
        #mutex.acquire()
        num_gob += 1
        #mutex.release()
    print(num_gob)
t1 = threading.Thread(target=task1,args=(100000,))
t2 = threading.Thread(target=task2,args=(100000,))

t1.start()
t2.start()

2.6 查看当前程序运行时的线程

import threading
import time

print (threading.enumerate())

def task3():
    print("4444444")
    time.sleep(1)

t = threading.Thread(target=task3)
t.start()

print(threading.enumerate())

time.sleep(5)
print(threading.enumerate())

#1、通过第4行的打印可以能够说明,当程序运行之后默认有1个线程。
#2、通过第10行创建一个Thread对象,第11行运行这个对象,且在第13行有两个线程,那么说明Thread真的创建了一个线程。
#3、当一个线程结束之后,第16行纸打印了一个线程,说明子线程已经结束了。

 

三、 python实现多协程

3.1 使用gevent实现协程

import gevent
import time
from gevent import monkey

monkey.patch_all()

def f1(n):
    for i in range(n):
        print ("------f1---------", i)
        time.sleep(1)
        #gevent.sleep(1)

def f2(n):
    for i in range(n):
        print ("------f2---------", i)
        time.sleep(1) 
        #gevent.sleep(1)   

def f3(n):
    for i in range(n):
        print ("------f3---------", i)
        time.sleep(1) 
        #gevent.sleep(1)

g1 = gevent.spawn(f1,5) 
g2 = gevent.spawn(f2,5) 
g3 = gevent.spawn(f3,5) 
g1.join()
g2.join()
g3.join()

3.2 使用gevent实现协程多任务

import gevent
import random
import time
from gevent import monkey

monkey.patch_all()

def coroutine_work(coroutine_name):
    for i in range(10):
        print(coroutine_name,i)
        time.sleep(random.random())

def coroutine_work2(coroutine_name):
    for i in range(10):
        print(coroutine_name,i)
        time.sleep(random.random())

gevent.joinall([
    gevent.spawn(coroutine_work,"work1"),
    gevent.spawn(coroutine_work2,"work2")

])

你可能感兴趣的:(python,开发语言)