进程通信与线程

Posted slookup

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程通信与线程相关的知识,希望对你有一定的参考价值。

一 、进程间通信(IPC机制)

队列:先进先出

堆栈:先进后出

利用队列实现进程间通信

from multiprocessing import Queue


q = Queue(5)      # 产生一个最多能够存放五个数据的队列

# q.put(1)      # 往队列中存放数据,如果存放的数据个数大于队列最大存储个数,程序会阻塞
# q.put(2)
# q.put(3)
# print(q.full())
q.put(4)
# q.put(5)
# print(q.full())
# for i in range(6):
# q.put(i)

# 存取数据
for i in range(5):
q.put(i)      # for循环往队列里面存放数据
print(q.get())      # 取数据,get一次就取一个
print(q.get())
print(q.get())
q.get_nowait()     # 在队列有数据的情况下,跟get取值一样,当队列没有数据的情况下,取值直接报错  

                            # q.get_nowait():同q.get(False)

print(q.empty())     # 判断队列是否为空,需要注意的是,在并发的情况下,这个方法判断不准确!
print(q.get())
print(q.get())
print(q.empty())
# q.get_nowait()
# print(q.get())     # 如果队列为空,get会在原地等待队列中有数据过来

 

 

二 、基于队列实现进程间通信 

from multiprocessing import Queue,Process


def producer(q):
q.put(‘hello baby!‘)


def consumer(q):
print(q.get())

if __name__ == ‘__main__‘:
q = Queue()       # 生成一个队列对象
p1 = Process(target=producer,args=(q,))
c1 = Process(target=consumer,args=(q,))
p1.start()
c1.start()

 

三 、 生产者消费者模型(重点)

 

"""
生产者:做包子的 生产数据的
消费者:买包子的 处理数据的

解决供需不平衡的问题
定义一个队列,用来存放固定数量的数据
解决一个生产者和消费者不需直接打交道,两者都通过队列实现数据传输

Queue:管道+锁
"""


from multiprocessing import Queue,Process,JoinableQueue
import time
import random


def producer(name,food,q):
for i in range(5):
data = ‘%s生产了%s%s‘%(name,food,i)
time.sleep(random.randint(1,3))
print(data)
q.put(data)       # 将生产的数据放入队列中


def consumer(name,q):
while True:
data = q.get()
if data is None:break
time.sleep(random.randint(1, 3))
print(‘%s吃了%s‘%(name,data))
q.task_done()       # 告诉你的队列,你已经将数据取出并且处理完毕


if __name__ == ‘__main__‘:
q = JoinableQueue()      # 生成一个队列对象
p1 = Process(target=producer,args=(‘大厨egon‘,‘包子‘,q))
p2 = Process(target=producer,args=(‘靓仔tank‘,‘生蚝‘,q))
c1 = Process(target=consumer,args=(‘吃货owen‘,q))
c2 = Process(target=consumer,args=(‘坑货kevin‘,q))
p1.start()
p2.start()
c1.daemon = True
c2.daemon = True
c1.start()
c2.start()
# 等待生产者生产完所有的数据
p1.join()
p2.join()
# 在生产者生产完数据之后,往队列里面放一个提示性的消息,告诉消费者已经没有数据,你走吧,不要等了
# q.put(None)
# q.put(None)
q.join()      # 等待队列中数据全部取出
print(‘主‘)

 

线程

1 、什么是线程?

    进程:资源单位

    线程:执行单位

    注意:每一个进程中都会自带一个线程

 

2 、为什么要有线程

    开一个进程:

      申请一个内存空间   耗时

      将代码拷贝到申请的内存空间中  耗时

    开线程:

      不需要申请内存空间

 

    开线程的开销远远小于开进程的开销!

 

3 、如何使用线程:几乎和进程一毛一样

 

一 、开启线程的两种方式

  

  方式一: 

 from threading import Thread
 import time

 def task(name):
 print(‘%s is running‘%name)
 time.sleep(1)
 print(‘%s is over‘%name)

 if __name__ == ‘__main__‘:
 t = Thread(target=task,args=(‘egon‘,))
 t.start()        # 开启线程的速度非常快,几乎代码执行完线程就已经开启
 print(‘主‘)

 

  方式二:

from threading import Thread
import time

class MyThread(Thread):
def __init__(self,name):
super().__init__()
self.name = name
def run(self):
print(‘%s is running‘ % self.name)
time.sleep(1)
print(‘%s is over‘%self.name)

if __name__ == ‘__main__‘:
t = MyThread(‘jason‘)
t.start()
print(‘主‘)

 

二 、线程之间数据共享

 

from threading import Thread

x = 100

def task():
global x
x = 666

t = Thread(target=task)
t.start()
t.join()
print(x)

 

-->>   1

 

三 、 线程互斥锁

 

from threading import Thread,Lock
import time

mutex = Lock()
n = 100

def task():
global n
mutex.acquire()        #加锁
tmp = n
time.sleep(0.1)
n = tmp -1
mutex.release()            #释放


t_list = []
for i in range(100):
t = Thread(target=task)
t.start()
t_list.append(t)

for t in t_list:
t.join()

print(n)

 

四 、 线程对象的其他属性和方法

 

from threading import Thread,active_count,current_thread
import os
import time


def task(name):
# print(‘%s is running‘%name,os.getpid())
print(‘%s is running‘%name,current_thread().name,current_thread().getName())
time.sleep(1)
print(‘%s is over‘%name)

def info(name):
print(‘%s is running‘ % name, current_thread().name, current_thread().getName())
time.sleep(1)
print(‘%s is over‘ % name)

t = Thread(target=task,args=(‘关磊‘,))
t1 = Thread(target=info,args=(‘关超‘,))
t.start()
t1.start()
t.join()
print(active_count())       # 当前存活的线程数
print(os.getpid())
print(current_thread().name)
print(current_thread().getName())

 

五 、 守护线程

 

from threading import Thread
import time


def task(name):
print(‘%s is running‘%name)
time.sleep(1)
print(‘%s is over‘%name)

if __name__ == ‘__main__‘:
t = Thread(target=task,args=(‘王磊‘,))
# t.daemon = True
t.start()
print(‘主‘)

 

以上是关于进程通信与线程的主要内容,如果未能解决你的问题,请参考以下文章

进程间通信与线程间通信

JAVA线程与线程进程与进程间通信

进程与线程 及之间通信

操作系统_进程同步与进程通信_多线程技术的优势

线程间的通信同步方式与进程间通信方式

进程间通信与线程