IPC机制/生产者消费者模型/线程开启的2种方式

上节课复习:

1.僵尸进程与孤儿进程

kill-CHLD查看父进程是否有僵尸进程                                    kill-9杀掉父进程

今日内容:

一:IPC机制(进程之间的通信)

真正进程之间的通信会用共享内存:

1.管道

 tasklist | findstr xxx

ps aux  | grep xxx

2.队列 是管道+锁实现的

from multiprocessing import Queue

q=Queue(3)                       #只能放3个值
q.put([1,2,3])                   #放值
q.put([4,5])                     
q.put([11,22,33])

print(q.get())                   #取值
print(q.get()) 

print(q.get())

print(q.get(block=False)) #一旦队列的值被取完之后,立马就抛出异常

结果是:
raise Empty _queue.Empty

只能在一台机上多个本地进程的使用,不适用于网络联机

二:生产者消费者模型******

p.jion的作用和用法

在主进程运行过程中如果想并发地执行其他的任务,我们可以开启子进程,此时主进程的任务与子进程的任务分两种情况

情况一:在主进程的任务与子进程的任务彼此独立的情况下,主进程的任务先执行完毕后,主进程还需要等待子进程执行完毕,然后统一回收资源。

情况二:如果主进程的任务在执行到某一个阶段时,需要等待子进程执行完毕后才能继续执行,就需要有一种机制能够让主进程检测子进程是否运行完毕,在子进程执行完毕后才继续执行,否则一直在原地阻塞,这就是join方法的作用

from multiprocessing import Process
import time
import random
import os

def task():
    print('%s is piaoing' %os.getpid())
    time.sleep(random.randrange(1,3))
    print('%s is piao end' %os.getpid())

if __name__ == '__main__':
    p=Process(target=task)
    p.start()
    p.join() #等待p停止,才执行下一行代码
    print('主')

该模型有两种角色,生产者和消费者;生产者负责产生数据,消费者负责取走数据;

生产者与消费者通过队列联系,优点是:解耦合,平衡了生产者的生产力与消费者的处理能力

from multiprocessing import Process,Queue
import time,random

def producer(q,name,food):
    for i in range(3):
        res='%s%s' %(food,i)
        time.sleep(random.randint(1,3))
        q.put(res)
        print('%s生产了 %s' %(name,res))

def consumer(q,name):
    while True:
        res=q.get()
        if res is None:        #配合下方的 q.get(None) 来解除在吃货把厨师的东西都吃完后进行原地死等
            break
        time.sleep(random.randint(1,3))
        print('%s 吃了 %s' %(name,res))

if __name__ == '__main__':
    q=Queue()

    p1=Process(target=producer,args=(q,'厨师1','包子'))
    p2=Process(target=producer,args=(q,'厨师2','烧麦'))
    p3=Process(target=producer,args=(q,'厨师3','馒头'))

    c1=Process(target=consumer,args=(q,'lxx'))
    c2=Process(target=consumer,args=(q,'hxx'))

    p1.start()
    p2.start()
    p3.start()
    c1.start()
    c2.start()

    p1.join()
    p2.join()
    p3.join()
    q.put(None)
    q.put(None)

    print('')
结果是:
厨师1生产了 包子0
厨师2生产了 烧麦0
厨师3生产了 馒头0
lxx 吃了 包子0
lxx 吃了 馒头0
hxx 吃了 烧麦0
厨师3生产了 馒头1
厨师1生产了 包子1
厨师2生产了 烧麦1
厨师1生产了 包子2
厨师2生产了 烧麦2
厨师3生产了 馒头2
主
hxx 吃了 包子1
lxx 吃了 馒头1
lxx 吃了 包子2
hxx 吃了 烧麦1
lxx 吃了 烧麦2
hxx 吃了 馒头2

三:线程理论******

1.定义

一条流水线式的过程,具体指的是进程内代码运行的过程

线程是一个执行单位,CPU执行的就是线程

(1)同一进程下的不同线程共享该进程的内存资源

(2)开启子线程的资源开销远远小于子进程

四:开启线程的2种方式******

方式1

from threading import Thread
import os

def task(name):
    print('%s is running' %name)

if __name__ == '__main__':
    t=Thread(target=task,args=('线程1',))
    t.start()
    print('主线程',os.getpid())

结果是:
线程1 is running
主线程 5628
验证主线程和子线程之间的隔离性

from
threading import Thread,current_thread import os n=100 def task(): n=0 if __name__ == '__main__': t=Thread(target=task) t.start() t.join() print('主线程',n) 结果是:主线程 100

方法2:

from threading import Thread

class Mythread(Thread):
    def __init__(self,name):
        super().__init__()
        self.name=name

    def run(self) -> None:
        print('%s is running' %self.name)

if __name__ == '__main__':
    t=Mythread('线程1')
    t.start()

结果是:
线程1 is running

五:守护线程

守护线程守护的是主线程的生命周期

六:互斥锁

from threading import  Thread,Lock
import os,time

n=100
mutex=Lock() #互斥锁
def task():
global n
with mutex: #互斥锁
temp=n
time.sleep(0.1)
n=temp-1
print(n)
if __name__ == '__main__':
mythread=[]
for i in range(100):
t=Thread(target=task)
mythread.append(t)
t.start()
for obj in mythread:
obj.join()
print('主',n) #结果是: 主,
原文地址:https://www.cnblogs.com/dayday-up-a/p/14307359.html