一、查看进程的id
'''
进程都有几个属性:进程名、进程id(pid --> process id)
每一个进程都有一个唯一的id号,通过这个id号就能找到这个进程
Linux -----> 杀进程 -----> kill -9 1001 -----> pkill 进程名
'''
import os
import time
from multiprocessing import Process
def task():
print('task中的子进程号:', os.getpid())
print('主进程中的进程号:', os.getppid())
time.sleep(5)
if __name__ == '__main__':
p = Process(target=task, )
p.start()
查看子进程p的进程号
print('子进程的进程号:', p.pid)
查看主进程的进程号
'''os.getgid()这一句写在哪个进程下,输出的就是这个进程的进程号'''
print('主进程的进程号:', os.getpid())
time.sleep(10)
二、队列的使用
"""
常见的数据结构:链表、单链表、双链表、循环链表、栈、队列、树、
二叉树、平衡二叉树、红黑树、b树、b+树、b-树、图等
队列:先进先出
"""
from multiprocessing import Queue
if __name__ == '__main__':
"""
思考:怎么样得到一个队列呢?
在python中,内置的有一个类,Queue
"""
队列的大小默认很大(2147483647)
q = Queue(3)
1.如何入队
q.put("helloworld")
q.put("helloworld1")
q.put("helloworld2")
2.出队
print(q.get())
print(q.get())
print(q.get())
print(q.get())
if __name__ == '__main__':
"""
思考:怎么样得到一个队列呢?
在python中,内置的有一个类,Queue
"""
q = Queue(3)
'''
put、get的参数有obj, block=True, timeout=None
'''
***********************************************************************
q.put("helloworld")
q.put("helloworld1")
q.put("helloworld2")
'''若指定了block参数,当队列满的时候,放不进去的时候,就会直接报错'''
'''若指定了timeout参数,当队列中放入数据的时候,等待3秒,如果放不进去,直接报错'''
'''往队列中放入数据的时候,放不进去直接报错'''
print(q.get())
print(q.get())
print(q.get())
'''注意:队列中剩余的数据量,这个方法的结果有点不准确'''
print(q.full())
三、解决进程之间的数据隔离问题
def task(q):
a = 1
q.put('子进程写入的数据')
q.put(a)
from multiprocessing import Process
from multiprocessing import Queue
if __name__ == '__main__':
q = Queue(3)
'''
若在子进程中放入一个数据,然后在主进程中取出这个数据,
若能取到,则说明主进程和子进程之间通信了。若不能,则说明没有通信
'''
p = Process(target=task, args=(q, ))
p.start()
'''在主进程中取出子进程写进去的数据'''
print(q.get())
print(q.get())
"""
现在队列中的数据在哪里存着?在内存中存着的,当数据量很大的时候,很占用机器的内存
注意:当前使用较多的消息队列有:RabbitMQ,RocketMQ,ActiveMQ、Kafka、ZeroMQ,MetaMQ
"""
四、生产者消费者模型
版本1:
def producer(q):
for i in range(10):
'''生成的东西放在哪里呢?队列里'''
q.put('这是第%s个' % i)
def consumer(q):
'''拿东西从哪里拿呢?也是队列中'''
while True:
res = q.get()
print(res)
from multiprocessing import Process
from multiprocessing import Queue
if __name__ == '__main__':
q = Queue(20)
p = Process(target=producer, args=(q, ))
p.start()
c = Process(target=consumer, args=(q, ))
c.start()
def producer(q):
for i in range(10):
'''生成的东西放在哪里呢?队列里'''
q.put('这是第%s个' % i)
q.put(None)
def consumer(q):
'''拿东西从哪里拿呢?也是队列中'''
while True:
res = q.get()
print(res)
'''若是有多个生产者,则不适宜用q.empty()'''
if res is None:
break
版本3:
def producer(q):
for i in range(10):
'''生成的东西放在哪里呢?队列里'''
q.put('这是第%s个' % i)
def consumer(q):
'''拿东西从哪里拿呢?也是队列中'''
while True:
res = q.get()
print(res)
'''若是有多个生产者,则不适宜用q.empty()'''
if res is None:
break
from multiprocessing import Process
from multiprocessing import Queue
if __name__ == '__main__':
q = Queue(20)
p = Process(target=producer, args=(q, ))
p.start()
c = Process(target=consumer, args=(q, ))
c.start()
'''
不能放在这个地方:是因为:开启进程有延迟,不会立刻开起来,
先执行主进程的代码,把None放在了队列的第一个,当消费者消费数据的时候,
直接就结束了
'''
q.put(None)
版本4:多生产者、少消费者
def producer(q, name, food):
for i in range(10):
'''生成的东西放在哪里呢?队列里'''
q.put('生产者:%s,生产了第%s个 %s' % (name, i, food))
def consumer(q):
'''拿东西从哪里拿呢?也是队列中'''
while True:
res = q.get()
'''若是有多个生产者,则不适宜用q.empty()'''
if res is None:
break
print(res)
from multiprocessing import Process
from multiprocessing import Queue
if __name__ == '__main__':
q = Queue(20)
p1 = Process(target=producer, args=(q, 'python', 'py'))
p2 = Process(target=producer, args=(q, 'java', 'main'))
p3 = Process(target=producer, args=(q, 'json', 'jjson'))
p4 = Process(target=producer, args=(q, 'golang', 'go'))
p1.start()
p2.start()
p3.start()
p4.start()
c1 = Process(target=consumer, args=(q,))
c2 = Process(target=consumer, args=(q,))
c1.start()
c2.start()
p1.join()
p2.join()
p3.join()
p4.join()
'''
不能放在这个地方:是因为:开启进程有延迟,不会立刻开起来,
先执行主进程的代码,把None放在了队列的第一个,当消费者消费数据的时候,
直接就结束了
'''
q.put(None)
q.put(None)
版本5:少生产者、多消费者
def producer(q, name, food):
for i in range(10):
'''生成的东西放在哪里呢?队列里'''
q.put('生产者:%s,生产了第%s个 %s' % (name, i, food))
def consumer(q):
'''拿东西从哪里拿呢?也是队列中'''
while True:
res = q.get()
'''若是有多个生产者,则不适宜用q.empty()'''
if res is None:
break
print(res)
from multiprocessing import Process
from multiprocessing import Queue
if __name__ == '__main__':
q = Queue(20)
p1 = Process(target=producer, args=(q, 'python', 'py'))
p2 = Process(target=producer, args=(q, 'java', 'main'))
p1.start()
p2.start()
c1 = Process(target=consumer, args=(q,))
c2 = Process(target=consumer, args=(q,))
c3 = Process(target=consumer, args=(q,))
c4 = Process(target=consumer, args=(q,))
c1.start()
c2.start()
c3.start()
c4.start()
p1.join()
p2.join()
q.put(None)
q.put(None)
q.put(None)
q.put(None)
五、线程相关
1.开启线程
'''
线程理论:
进程是一个任务的执行过程,在这个过程中实际做事的是线程,线程是开在进程里面的,
需要先有进程,再有线程,一个进程中至少有一个线程,当然,也可以有多个线程
进程是自愿分配的基本单位,线程是CPU执行的最小单位
进程和线程都是由操作系统来调度的,协程是由程序员来调度的
进程 >>> 线程 >>> 协程
资源消耗最多的 >>> 线程的资源 >>> 协程
'''
from multiprocessing import Process
from threading import Thread
import threading
def task(name, name1, age):
print('task执行了')
print(name)
print(name1)
print(age)
print(threading.currentThread())
if __name__ == '__main__':
"""
参数:
group=None, target=None, name=None,
args=(), kwargs=None, *, daemon=None
修改线程名称:
name = 'name1'
"""
t = Thread(target=task, name='lin', args=('kevin', 'tank'), kwargs={'age': 18})
t.start()
print(123)
print(t.is_alive())
print(t.getName())
t.setName('duck')
print(t.name)
print(465)
print(threading.currentThread())
2.开启多线程
from threading import Thread
def task(i):
print(i)
if __name__ == '__main__':
tt = []
for i in range(5):
t = Thread(target=task, args=(i, ))
t.start()
tt.append(t)
for j in tt:
j.join()
print('开启多线程')
print(123)
六、进程和线程之间的比较
import time
from multiprocessing import Process
from threading import Thread
def work():
print('hello')
time.sleep(1)
if __name__ == '__main__':
start_time = time.time()
p = Process(target=work)
p.start()
p.join()
print('主线程/主进程')
print('time:', time.time() - start_time)
'''
执行的时间不一样,线程的时间远远小于进程的执行时间
'''
七、修改线程的数据
def work():
print('hello')
global n
n = 0
if __name__ == '__main__':
n = 1
t = Thread(target=work)
t.start()
t.join()
print('n=', n)