Python学习 第13章-进程与线程

文章详细介绍了Python的multiprocessing模块中的Process类及其使用,包括创建子进程、常用属性和方法,以及线程的Thread类、线程安全、进程池、队列的使用,展示了生产者-消费者问题的解决方案。还涉及了进程间数据共享和同步机制如锁的使用。
摘要由CSDN通过智能技术生成

本章内容:

本章示例:

示例13-1Multiprocessing模块创建进程

from multiprocessing import Process
import os,time
def test():
    print(f'我是子进程,我的PIP是:{os.getpid()},我的父进程是:{os.getppid()}')
    time.sleep(1)

lst=[]
if __name__ == '__main__':
    print('主进程开始执行')
    #创建5个子进程
    for i in range(5):
        p=Process(target=test)
        #启动子进程
        p.start()
        #启动中的进程添加到列表中
        lst.append(p)
    for item in lst:
        item.join()#阻塞主进程
    print('主进程执行结束')

示例13-2Process类中常用的属性和方法

from multiprocessing import Process
import os,time
def sub_process(name):
    print(f'子进程的PID是:{os.getpid()},父进程的PPID是:{os.getppid()},-------{name}')
    time.sleep(1)

def sub_process2(name):
    print(f'子进程的PID是:{os.getpid()},父进程的PPID是:{os.getppid()},-------{name}')
    time.sleep(1)

if __name__ == '__main__':
    print('父进程开始执行')
    for i in range(5):
        p1=Process(target=sub_process,args=('ysj',))
        p2=Process(target=sub_process2,args=(18,))
        p1.start()
        p2.start()
        print(p1.name,'是否执行完毕',p1.is_alive())
        print(p2.name,'是否执行完毕',p2.is_alive())

        print(p1.name,'pid是:',p1.pid)
        print(p2.name,'pid是:',p2.pid)

        p1.join()
        p2.join()
    print('父进程执行结束')

示例13-3Process类中常用的属性和方法2

from multiprocessing import Process
import os,time
def sub_process(name):
    print(f'子进程的PID是:{os.getpid()},父进程的PPID是:{os.getppid()},-------{name}')
    time.sleep(1)

def sub_process2(name):
    print(f'子进程的PID是:{os.getpid()},父进程的PPID是:{os.getppid()},-------{name}')
    time.sleep(1)

if __name__ == '__main__':
    print('主进程开始执行')
    for i in range(5):
        p1=Process(target=sub_process,args=('ysj',))
        p2=Process(target=sub_process2,args=(18,))
        p1.start() #Process如果没有指定参数,会调用run方法
        p2.start() #指定了参数后,会调用指定的方法


        p1.terminate() #强制终止进程
        p2.terminate()

    print('主进程执行结束')

示例13-4使用Process子类创建进程

from multiprocessing import Process
import os,time

class SubProcess(Process):

    def __init__(self,name):
        super().__init__()
        self.name=name

    def run(self):
        print(f'子进程的名称{self.name},PID:{os.getpid()},父进程的PID:{os.getppid()}')

if __name__ == '__main__':
    print('主进程开始执行')
    lst=[]
    for i in range(1,6):
        p1=SubProcess(f'进程:{i}')

        p1.start()
        lst.append(p1)

    for item in lst:
        item.join()

    print('主进程执行结束')

示例13-5使用进程池-非阻塞方式

from multiprocessing import Pool
import time,os
def task(name):
    print(f'子进程的PID:{os.getpid()},执行的任务:{name}')
    time.sleep(1)

if __name__ == '__main__':
    start=time.time()
    print('主进程开始执行')

    p=Pool(3)
    for i in range(10):
        p.apply_async(func=task,args=(i,))

    p.close()
    p.join()
    print('所有子进程执行完毕,主进程执行结束')
    print(time.time()-start)

示例13-6使用进程池-阻塞方式

from multiprocessing import Pool
import time,os
def task(name):
    print(f'子进程的PID:{os.getpid()},执行的任务:{name}')
    time.sleep(1)

if __name__ == '__main__':
    start=time.time()
    print('主进程开始执行')

    p=Pool(3)
    for i in range(10):
        p.apply(func=task,args=(i,))

    p.close()
    p.join()
    print('所有子进程执行完毕,主进程执行结束')
    print(time.time()-start)

示例13-7多个进程之间数据是否共享

from multiprocessing import Process
a=100


def add():
    print('子进程1开始执行')
    global a
    a+=30
    print('a=',a)
    print('子进程1执行完毕')


def sub():
    print('子进程2开始执行')
    global a
    a-=50
    print('a=',a)
    print('子进程2执行完毕')

if __name__ == '__main__':
    print('主进程开始执行')
    print('a=',a)
    p1=Process(target=add)
    p2=Process(target=sub)

    p1.start()
    p2.start()

    p1.join()
    p2.join()

    print('主进程执行结束')
    print('a=',a)

示例13-8队列的基本使用

from multiprocessing import Queue

if __name__ == '__main__':
    # 创建一个队列
    q = Queue(3)
    print('队列是否为空:', q.empty())
    print('队列是否为满:', q.full())
    # 向队列中添加消息
    q.put('hello')
    q.put('world')
    print('队列是否为空:', q.empty())
    print('队列是否为满:', q.full())
    q.put('Python')
    print('队列是否为空:', q.empty())
    print('队列是否为满:', q.full())
    print('队列当中有多少消息:', q.qsize())
    #出队
    print(q.get())
    print('队列中信息个数:',q.qsize())
    #入队
    q.put_nowait('html')
    # q.put_nowait('sql') #queue.Full
    # q.put('sql') #不报错,一直等待,直到队列中有空位
    #遍历
    if not q.empty():
        for i in range(q.qsize()):
            print(q.get_nowait())
    print('队列是否为空:',q.empty())
    print('队列是否为满:',q.full())
    print('队列当中有多少消息:', q.qsize())

此示例中macOS无法运行qsize()方法,暂时没有找到解决办法

示例13-9向已满的队列中添加元素

from multiprocessing import Queue
if __name__ == '__main__':
    q=Queue(3)
    q.put('hello')
    q.put('world')
    q.put('python')

    q.put('html')

示例13-10设置put方法的参数

from multiprocessing import Queue
if __name__ == '__main__':
    q=Queue(3)
    q.put('hello')
    q.put('world')
    q.put('python')

    q.put('html',block=True,timeout=2)

示例13-11使用队列实现进程之间的通信

from multiprocessing import Queue,Process
import time
a=100
def write_msg(q):
    global a
    if not q.full():
        for i in range(6):
            a-=10
            q.put(a)
            print('a入队时的值',a)

def read_msg(q):
    time.sleep(1)
    while not q.empty():
        print('出队时a的值:',q.get())
if __name__ == '__main__':
    print('主进程开始执行')
    q=Queue()
    p1=Process(target=write_msg,args=(q,))
    p2=Process(target=read_msg,args=(q,))

    p1.start()
    p2.start()

    p1.join()
    p2.join()
    print('主进程执行完毕')

示例13-12函数方式创建线程

import threading
from threading import Thread
import time
def test():
    for i in range(3):
        time.sleep(1)
        print(f'线程{threading.current_thread().name}正在执行{i}')

if __name__ == '__main__':
    start=time.time()
    print('主线程开始执行')

    lst=[Thread(target=test) for i in range(2)]

    for item in lst:
        item.start()
    for item in lst:
        item.join()
    print(f'一共耗时:{time.time()-start}')

示例13-13使用Thread子类创建线程

import threading
from threading import Thread
import time
class SubThread(Thread):
    def run(self):
        for i in range(3):
            time.sleep(1)
            print(f'线程{threading.current_thread().name}正在执行{i}')


if __name__ == '__main__':
    print('主进程开始执行')
    lst=[SubThread() for i in range(2)]
    for item in lst:
        item.start()
    for item in lst:
        item.join()
    print('主线程执行完毕')

示例13-14线程之间的数据是否共享

from threading import Thread
a=100
def add():
    print('加线程开始执行')
    global a
    a+=30
    print('a=',a)
    print('加线程执行结束')
def sub():
    print('减线程开始执行')
    global a
    a-=50
    print('a=',a)
    print('减线程执行结束')
if __name__ == '__main__':
    print('主线程执行')
    print('全局变量a=',a)
    add=Thread(target=add)
    sub=Thread(target=sub)

    add.start()
    sub.start()

    add.join()
    sub.join()
    print('主线程执行结束')

示例13-15线程共享数据所带来的安全性问题

import threading
from threading import Thread
import time
ticket=50
def sale_ticket():
    global ticket

    for i in range(100):
        if ticket>0:
            print(f'{threading.current_thread().name}正在出售第{ticket}张票')
            ticket-=1
        time.sleep(1)
if __name__ == '__main__':
    for i in range(3):
        t=Thread(target=sale_ticket)
        t.start()

示例13-16使用lock锁

import threading
from threading import Thread,Lock
import time
ticket=50
lock_obj=Lock()#创建锁对象

def sale_ticket():
    global ticket

    for i in range(100):
        lock_obj.acquire()
        if ticket>0:
            print(f'{threading.current_thread().name}正在出售第{ticket}张票')
            ticket-=1
        time.sleep(1)

        lock_obj.release()

if __name__ == '__main__':
    for i in range(3):
        t=Thread(target=sale_ticket)
        t.start()

示例13-17使用队列实现生产者和消费者的问题

from queue import Queue
from threading import Thread
import time
#创建一个生产者类
class Producer(Thread):
    def __init__(self,name,queue):
        Thread.__init__(self,name=name)
        self.queue=queue

    def run(self):
        for i in range(1,6):
            print(f'{self.name}将产品{i}放入队列')
            self.queue.put(i)
            time.sleep(1)
        print('生产者完成了所有数据的存放')

#创建一个消费者类:
class Consumer(Thread):
    def __init__(self,name,queue):
        Thread.__init__(self,name=name)
        self.queue=queue
    def run(self):
        for i in range(5):
            value=self.queue.get()
            print(f'消费者线程:{self.name}取出了{value}')
        print('----------消费者线程完成了所有数据的取出---------')
if __name__ == '__main__':
    queue=Queue()
    p=Producer('Producer',queue)
    c=Consumer('Consumer',queue)

    p.start()
    c.start()

    p.join()
    c.join()
    print('主线程执行结束')

注:本文中的内容和示例均出自@Python_子木的视频

 

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值