os.getpid()
是 Python 的一个内置函数,它返回当前进程的进程ID。在 Unix 和 Windows 系统中,每个进程都有一个唯一的ID,这个ID是一个整数。在 Python 中,你可以使用 os.getpid()
函数来获取当前进程的ID。
id()
函数返回对象的唯一标识符,这个标识符是Python内部使用的,通常是一个大的整数。对于同一个对象,每次调用id()
函数都会返回相同的值。
import os,time
import multiprocessing
def watch():
for i in range(3):
print("watching TV...",os.getpid())
time.sleep(1)
if __name__=="__main__":
process1=multiprocessing.Process(target=watch)
process2=multiprocessing.Process(target=watch)
process1.start()
process2.start()
"""
watching TV... 1988
watching TV... 14976
watching TV... 1988
watching TV... 14976
watching TV... 1988
watching TV... 14976
"""
import multiprocessing
import os
import time
def watch():
for i in range(3):
print(f"watching TV....epoce:{i} {os.getpid()}")
time.sleep(1)
def eat(food):
for i in range(3):
print(f"eat {food}.......epoce:{i} ",os.getpid())
time.sleep(1)
def drink(beverage):
for i in range(3):
print(f"drink {beverage}...epoce:{i} ",os.getpid())
time.sleep(1)
if __name__=="__main__":
print("main process",os.getpid())
watch_pro=multiprocessing.Process(target=watch)
eat_pro= multiprocessing.Process(target=eat,args=("pork",))
drink_pro=multiprocessing.Process(target=drink,kwargs={"beverage":"coffee"})
watch_pro.start()
drink_pro.start()
eat_pro.start()
print("main process stop...")
"""
main process 14360
main process stop...
watching TV....epoce:0 8084
drink coffee...epoce:0 6684
eat pork.......epoce:0 11540
watching TV....epoce:1 8084
drink coffee...epoce:1 6684
eat pork.......epoce:1 11540
watching TV....epoce:2 8084
drink coffee...epoce:2 6684
eat pork.......epoce:2 11540
"""
import multiprocessing
import os
import time
class Human(object):
def watch(self):
for i in range(3):
print(f"watching TV....epoce:{i} {os.getpid()}")
time.sleep(1)
def eat(self,food):
for i in range(3):
print(f"eat {food}.......epoce:{i} ",os.getpid())
time.sleep(1)
def drink(self,beverage):
for i in range(3):
print(f"drink {beverage}...epoce:{i} ",os.getpid())
time.sleep(1)
if __name__=="__main__":
jack=Human()
print("main process",os.getpid())
watch_pro=multiprocessing.Process(target=jack.watch)
eat_pro= multiprocessing.Process(target=jack.eat,args=("pork",))
drink_pro=multiprocessing.Process(target=jack.drink,kwargs={"beverage":"coffee"})
eat_pro2=multiprocessing.Process(target=jack.eat)
watch_pro.start()
drink_pro.start()
eat_pro.start()
print("main process stop...")
"""
main process 2272
main process stop...
watching TV....epoce:0 21704
drink coffee...epoce:0 16804
eat pork.......epoce:0 14428
watching TV....epoce:1 21704
drink coffee...epoce:1 16804
eat pork.......epoce:1 14428
watching TV....epoce:2 21704
drink coffee...epoce:2 16804
eat pork.......epoce:2 14428
"""
"""
继承process类创建进程
"""
from multiprocessing import Process
import os
import time
class MyProcess(Process):
def __init__(self,name):
super().__init__()
self.name = name
def run(self):
for i in range(3):
print(f'{self.name}{i} is running...{os.getpid()}')
time.sleep(1)
if __name__=="__main__":
p1=MyProcess("love")
p2=MyProcess("desk")
p3=MyProcess("vary")
p1.start()
p2.start()
p3.start()
进程之间是互相独立的,主进程代码运行结束,守护进程随即终止(主进程和子进程是异步的),当主进程停止,该守护进程不在继续执行.守护进程也是一种子进程.
主进程创建守护进程
其一:守护进程会在主进程代码执行结束后就终止.(但本质上是在主进程结束之前结束的,主进程需要负责回收资源)
其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children
主进程比守护进程先结束,因此,主进程打印结果能输出,而守护进程来不及执行它自己的程序而被迫终止
import time
from multiprocessing import Process
def mydaemon():
while True:
print("daemon is alive!")
time.sleep(1)
if __name__ == '__main__':
p = Process(target=mydaemon)
p.daemon = True # 设为守护进程,必须写在start()方法之前
p.start()
print("main process ended.")
"""
运行结果:
main process ended.
"""
主进程比守护进程晚结束,因此,主进程打印结果能输出,而守护进程也有时间在主进程结束之前,执行守护进程自己的程序
import time
from multiprocessing import Process
def mydaemon():
while True:
print("daemon is alive!")
time.sleep(1)
if __name__ == '__main__':
p = Process(target=mydaemon)
p.daemon = True # 设置当前子进程为守护进程,必须写在start()方法之前
p.start()
time.sleep(5)
print("main process ended.")
"""
运行结果:
daemon is alive!
daemon is alive!
daemon is alive!
daemon is alive!
daemon is alive!
main process ended.
"""
创建warehouse.txt来存储票数
{"amount": 4}
"""
加锁:买票
"""
import json
import time
from multiprocessing import Process,Lock
#多进程同时打开操作同一个文件,就会出现资源冲突导致的报错问题
def get_ticket(username):
"""查询余票"""
time.sleep(0.01)
data=json.load(open("warehouse.txt","r"))
print(f"{username}查询余票:{data['amount']}")
def buy_ticket(username):
"""购买车票"""
time.sleep(0.01)
data=json.load(open("warehouse.txt","r"))
#有票,购买成功
if data["amount"] > 0:
data["amount"]-=1
print(f"{username}成功购买车票!")
else:
print(f"{username}购买车票失败!")
time.sleep(0.01)
#把票的数据放入仓库
json.dump(data,open("warehouse.txt","w"))
def task(username,lock):
get_ticket(username)
#给需要加锁的代码设置加锁和释放锁操作
lock.acquire()#加锁
buy_ticket(username)
lock.release()#解锁
if __name__ == '__main__':
#在主进程中,创建锁
lock=Lock()
for i in range(10):
# 把锁传递到需要加锁的每个子进程中
p = Process(target=task, args=(f"user-{i}", lock))
p.start()
user-1查询余票:4
user-0查询余票:4
user-1成功购买车票!
user-2查询余票:4
user-4查询余票:4
user-3查询余票:3
user-0成功购买车票!
user-5查询余票:3
user-6查询余票:2
user-7查询余票:2
user-2成功购买车票!
user-8查询余票:2
user-9查询余票:2
user-4成功购买车票!
user-3购买车票失败!
user-5购买车票失败!
user-6购买车票失败!
user-7购买车票失败!
user-8购买车票失败!
user-9购买车票失败!
get_ticket(username)
#给需要加锁的代码设置加锁和释放锁操作
lock.acquire()#加锁
buy_ticket(username)
#假如:buy_ticket()方法中,或者这里发生了运行错误,则运行的进程阻塞不释放锁。
#这导致其他进程也一直处于等待中,拿不到锁
lock.release()#解锁
"""
改进的买票
"""
import json
import time
from multiprocessing import Process,Lock
def get_ticket(username):
"""查询余票"""
time.sleep(0.01)
data=json.load(open("ticket.txt","r"))
print(f"{username}查询余票:{data['count']}")
def buy_ticket(username):
"""购买车票"""
time.sleep(0.01)
data=json.load(open("ticket.txt","r"))
#有票,购买成功
if data["count"] > 0:
data["count"]-=1
print(f"{username}成功购买车票!")
else:
print(f"{username}购买车票失败!")
time.sleep(0.01)
#把票的数据放入仓库
json.dump(data,open("ticket.txt","w"))
def task(username,lock):
get_ticket(username)
# 采用with lock的方式对程序进行加锁,被加锁的代码发生错误了,也可以自动解锁
with lock:#__enter__和__exit__
buy_ticket(username)
if __name__ == '__main__':
#在主进程中,创建锁
lock=Lock()
for i in range(10):
# 把锁传递到需要加锁的每个子进程中
p = Process(target=task, args=(f"user-{i}", lock))
p.start()