python multiprocessing lock锁在相同父进程ID起作用
python多进程之间实现数据共享需要使用queue队列,全局变量不起作用
lock锁在同一个主进程ID下子进程ID之间起作用,不同的主进程ID互不干扰
下面来看代码
import multiprocessing,time,datetime
a=1
def demo1():
global a
a+=1
print('进程1',a,datetime.datetime.now())
def demo2():
time.sleep(2)
print('进程2',a,datetime.datetime.now())
def demo3():
print('开始执行进程3')
lock.acquire()
for i in range(5):
time.sleep(2)
q.put(i)
lock.release()
print('进程3',datetime.datetime.now())
def demo4():
print('开始执行进程4')
time.sleep(1)
while not q.empty():
print('进程4获取值:',q.get())
time.sleep(2)
print('进程4',datetime.datetime.now())
q=multiprocessing.Queue()
lock=multiprocessing.Lock()
multiprocessing.Process(target=demo1).start()
multiprocessing.Process(target=demo2).start()
multiprocessing.Process(target=demo3).start()
multiprocessing.Process(target=demo4).start()
运行结果
(python38) [root@mysql01 dtask]# python 2.py
开始执行进程3
开始执行进程4
进程1 2 2024-10-25 15:29:38.662167
进程2 1 2024-10-25 15:29:40.662385
进程4 2024-10-25 15:29:41.666102
进程3 2024-10-25 15:29:48.670803
可以看到进程1结果是2 进程2结果是1
进程2还可以延迟,global在这个里面没有起效果
然后进程3和进程4 lock锁只对进程3有作用,并没有对进程4有任何作用,因为进程4无需持有锁,所以不受锁干扰
下面单独写一个进程
import multiprocessing,time,datetime,os
def demo():
time.sleep(1)
print('执行时间:',datetime.datetime.now(),f'子进程名字:{multiprocessing.current_process().name},当前进程ID:{os.getpid()},父进程ID:{os.getppid()}')
q=multiprocessing.Queue()
t=[]
lock=multiprocessing.Lock()
for i in range(10):
t.append(multiprocessing.Process(target=demo,name=f'进程{i}'))
for i in t:
i.start()
可以看到运行之后基本都是并发执行,这也是多进程效果更
(python38) [root@mysql01 dtask]# python 2.py
执行时间: 2024-10-25 15:44:45.548511 子进程名字:进程5,当前进程ID:7678,父进程ID:7672
执行时间: 2024-10-25 15:44:45.549113 子进程名字:进程6,当前进程ID:7679,父进程ID:7672
执行时间: 2024-10-25 15:44:45.549570 子进程名字:进程1,当前进程ID:7674,父进程ID:7672
执行时间: 2024-10-25 15:44:45.549994 子进程名字:进程2,当前进程ID:7675,父进程ID:7672
执行时间: 2024-10-25 15:44:45.550426 子进程名字:进程3,当前进程ID:7676,父进程ID:7672
执行时间: 2024-10-25 15:44:45.550839 子进程名字:进程7,当前进程ID:7680,父进程ID:7672
执行时间: 2024-10-25 15:44:45.551425 子进程名字:进程8,当前进程ID:7681,父进程ID:7672
执行时间: 2024-10-25 15:44:45.551954 子进程名字:进程9,当前进程ID:7682,父进程ID:7672
执行时间: 2024-10-25 15:44:45.552496 子进程名字:进程4,当前进程ID:7677,父进程ID:7672
执行时间: 2024-10-25 15:44:45.553263 子进程名字:进程0,当前进程ID:7673,父进程ID:7672
(python38) [root@mysql01 dtask]# python 2.py
执行时间: 2024-10-25 15:44:49.854005 子进程名字:进程5,当前进程ID:7692,父进程ID:7686
执行时间: 2024-10-25 15:44:49.854485 子进程名字:进程6,当前进程ID:7693,父进程ID:7686
执行时间: 2024-10-25 15:44:49.854808 子进程名字:进程1,当前进程ID:7688,父进程ID:7686
执行时间: 2024-10-25 15:44:49.855316 子进程名字:进程2,当前进程ID:7689,父进程ID:7686
执行时间: 2024-10-25 15:44:49.855698 子进程名字:进程3,当前进程ID:7690,父进程ID:7686
执行时间: 2024-10-25 15:44:49.856247 子进程名字:进程7,当前进程ID:7694,父进程ID:7686
执行时间: 2024-10-25 15:44:49.856574 子进程名字:进程8,当前进程ID:7695,父进程ID:7686
执行时间: 2024-10-25 15:44:49.857254 子进程名字:进程9,当前进程ID:7696,父进程ID:7686
执行时间: 2024-10-25 15:44:49.857582 子进程名字:进程4,当前进程ID:7691,父进程ID:7686
执行时间: 2024-10-25 15:44:49.858258 子进程名字:进程0,当前进程ID:7687,父进程ID:7686
下面采用lock
import multiprocessing,time,datetime,os
def demo():
lock.acquire()
time.sleep(1)
print('执行时间:',datetime.datetime.now(),f'子进程名字:{multiprocessing.current_process().name},当前进程ID:{os.getpid()},父进程ID:{os.getppid()}')
lock.release()
q=multiprocessing.Queue()
t=[]
lock=multiprocessing.Lock()
for i in range(10):
t.append(multiprocessing.Process(target=demo,name=f'进程{i}'))
for i in t:
i.start()
运行结果:
python38) [root@mysql01 dtask]# python 2.py
执行时间: 2024-10-25 15:46:15.888807 子进程名字:进程5,当前进程ID:7789,父进程ID:7783
执行时间: 2024-10-25 15:46:16.889815 子进程名字:进程6,当前进程ID:7790,父进程ID:7783
执行时间: 2024-10-25 15:46:17.891551 子进程名字:进程1,当前进程ID:7785,父进程ID:7783
执行时间: 2024-10-25 15:46:18.893307 子进程名字:进程2,当前进程ID:7786,父进程ID:7783
执行时间: 2024-10-25 15:46:19.895166 子进程名字:进程3,当前进程ID:7787,父进程ID:7783
执行时间: 2024-10-25 15:46:20.896928 子进程名字:进程7,当前进程ID:7791,父进程ID:7783
执行时间: 2024-10-25 15:46:21.898912 子进程名字:进程8,当前进程ID:7792,父进程ID:7783
执行时间: 2024-10-25 15:46:22.900966 子进程名字:进程9,当前进程ID:7793,父进程ID:7783
执行时间: 2024-10-25 15:46:23.902843 子进程名字:进程4,当前进程ID:7788,父进程ID:7783
执行时间: 2024-10-25 15:46:24.904852 子进程名字:进程0,当前进程ID:7784,父进程ID:7783
可以看到时间都是相差一秒顺序执行所以没问题
看一个不同函数名获取lock的
import multiprocessing,time,datetime,os
def demo():
lock.acquire()
time.sleep(1)
q.put(1)
print('执行时间:',datetime.datetime.now(),f'子进程名字:{multiprocessing.current_process().name},当前进程ID:{os.getpid()},父进程ID:{os.getppid()}')
lock.release()
def demo2():
lock.acquire()
time.sleep(1)
q.put(2)
print('执行时间:',datetime.datetime.now(),f'子进程名字:{multiprocessing.current_process().name},当前进程ID:{os.getpid()},父进程ID:{os.getppid()}')
lock.release()
q=multiprocessing.Queue()
t=[]
lock=multiprocessing.Lock()
t.append(multiprocessing.Process(target=demo,name=f'进程1'))
t.append(multiprocessing.Process(target=demo2,name=f'进程2'))
for i in t:
i.start()
for i in t:
i.join()
while not q.empty():
print('q的值:',q.get())
运行结果:
(python38) [root@mysql01 dtask]# python 2.py
执行时间: 2024-10-25 15:55:21.224533 子进程名字:进程2,当前进程ID:8403,父进程ID:8401
执行时间: 2024-10-25 15:55:22.226918 子进程名字:进程1,当前进程ID:8402,父进程ID:8401
q的值: 2
q的值: 1
修改下代码:
import multiprocessing,time,datetime,os
def demo():
lock.acquire()
time.sleep(1)
q.put(1)
print('执行时间:',datetime.datetime.now(),f'子进程名字:{multiprocessing.current_process().name},当前进程ID:{os.getpid()},父进程ID:{os.getppid()}')
lock.release()
def demo2():
# lock.acquire()
time.sleep(1)
q.put(2)
print('执行时间:',datetime.datetime.now(),f'子进程名字:{multiprocessing.current_process().name},当前进程ID:{os.getpid()},父进程ID:{os.getppid()}')
# lock.release()
q=multiprocessing.Queue()
t=[]
lock=multiprocessing.Lock()
t.append(multiprocessing.Process(target=demo,name=f'进程1'))
t.append(multiprocessing.Process(target=demo2,name=f'进程2'))
for i in t:
i.start()
for i in t:
i.join()
while not q.empty():
print('q的值:',q.get())
结果:
(python38) [root@mysql01 dtask]# python 2.py
执行时间: 2024-10-25 15:57:27.649754 子进程名字:进程1,当前进程ID:8534,父进程ID:8533
执行时间: 2024-10-25 15:57:27.651128 子进程名字:进程2,当前进程ID:8535,父进程ID:8533
q的值: 1
q的值: 2
可以看到lock锁对在同一个父进程ID,会起到锁的作用
接下来我们建一个1.py脚本
脚本内容
import multiprocessing,time,datetime,os
def demo():
lock.acquire()
time.sleep(10)
q.put(1)
print('执行时间:',datetime.datetime.now(),f'子进程名字:{multiprocessing.current_process().name},当前进程ID:{os.getpid()},父进程ID:{os.getppid()}')
lock.release()
def demo2():
lock.acquire()
time.sleep(10)
q.put(2)
print('执行时间:',datetime.datetime.now(),f'子进程名字:{multiprocessing.current_process().name},当前进程ID:{os.getpid()},父进程ID:{os.getppid()}')
lock.release()
q=multiprocessing.Queue()
t=[]
lock=multiprocessing.Lock()
t.append(multiprocessing.Process(target=demo,name=f'进程1'))
t.append(multiprocessing.Process(target=demo2,name=f'进程2'))
print('1.py脚本主程序开始执行时间',datetime.datetime.now())
for i in t:
i.start()
for i in t:
i.join()
while not q.empty():
print('q的值:',q.get())
2.py文件内容
import multiprocessing,time,datetime,os
def demo():
lock.acquire()
time.sleep(1)
q.put(1)
print('执行时间:',datetime.datetime.now(),f'子进程名字:{multiprocessing.current_process().name},当前进程ID:{os.getpid()},父进程ID:{os.getppid()}')
lock.release()
def demo2():
# lock.acquire()
time.sleep(1)
q.put(2)
print('执行时间:',datetime.datetime.now(),f'子进程名字:{multiprocessing.current_process().name},当前进程ID:{os.getpid()},父进程ID:{os.getppid()}')
# lock.release()
q=multiprocessing.Queue()
t=[]
lock=multiprocessing.Lock()
t.append(multiprocessing.Process(target=demo,name=f'进程1'))
t.append(multiprocessing.Process(target=demo2,name=f'进程2'))
print('2.py脚本主程序开始执行时间',datetime.datetime.now())
for i in t:
i.start()
for i in t:
i.join()
while not q.empty():
print('q的值:',q.get())
同时执行1.py 和 2.py运行结果
(python38) [root@mysql01 dtask]# python 2.py
2.py脚本主程序开始执行时间 2024-10-25 16:11:22.094498
执行时间: 2024-10-25 16:11:23.097780 子进程名字:进程1,当前进程ID:9620,父进程ID:9619
执行时间: 2024-10-25 16:11:23.098284 子进程名字:进程2,当前进程ID:9621,父进程ID:9619
q的值: 1
q的值: 2
(python38) [root@mysql01 dtask]# python 1.py
1.py脚本主程序开始执行时间 2024-10-25 16:11:19.230205
执行时间: 2024-10-25 16:11:29.242953 子进程名字:进程1,当前进程ID:9615,父进程ID:9614
执行时间: 2024-10-25 16:11:39.254650 子进程名字:进程2,当前进程ID:9616,父进程ID:9614
q的值: 1
q的值: 2
还有文件输入情况,如果对文件进行lock,如果另外一个没加锁也是一样效果
import multiprocessing,time,datetime,os
def demo():
lock.acquire()
time.sleep(10)
# for i in range(10):
# q.put(f'demo-{i}')
with open('1.txt','a+',encoding='utf-8') as f:
for i in range(10):
print('开始写入demo数据')
f.write(f'demo-{i}\n')
f.flush()
print('执行时间1:',datetime.datetime.now(),f'子进程名字:{multiprocessing.current_process().name},当前进程ID:{os.getpid()},父进程ID:{os.getppid()}')
lock.release()
def demo2():
# lock.acquire()
# for i in range(10,20):
# q.put(f'demo2-{i}')
print(f'开始时间:{datetime.datetime.now()}')
with open('1.txt','a+',encoding='utf-8') as f:
for i in range(11,40):
time.sleep(1)
print('开始写入demo2数据')
f.write(f'demo2-{i}\n')
f.flush()
print('执行时间2:',datetime.datetime.now(),f'子进程名字:{multiprocessing.current_process().name},当前进程ID:{os.getpid()},父进程ID:{os.getppid()}')
# lock.release()
q=multiprocessing.Queue()
t=[]
lock=multiprocessing.Lock()
t.append(multiprocessing.Process(target=demo,name=f'进程1'))
t.append(multiprocessing.Process(target=demo2,name=f'进程2'))
print('1.py脚本主程序开始执行时间',datetime.datetime.now())
for i in t:
i.start()
for i in t:
i.join()
while not q.empty():
print('q的值:',q.get())
print('程序结束时间:',datetime.datetime.now())
执行结果
(python38) [root@mysql01 dtask]# python 1.py
1.py脚本主程序开始执行时间 2024-10-28 15:09:06.458782
开始时间:2024-10-28 15:09:06.460716
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo数据
开始写入demo数据
开始写入demo数据
开始写入demo数据
开始写入demo数据
开始写入demo数据
开始写入demo数据
开始写入demo数据
开始写入demo数据
开始写入demo数据
执行时间1: 2024-10-28 15:09:16.470825 子进程名字:进程1,当前进程ID:16878,父进程ID:16877
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
开始写入demo2数据
执行时间2: 2024-10-28 15:09:35.521156 子进程名字:进程2,当前进程ID:16879,父进程ID:16877
程序结束时间: 2024-10-28 15:09:35.521762
(python38) [root@mysql01 dtask]# more 1.txt
demo2-11
demo2-12
demo2-13
demo2-14
demo2-15
demo2-16
demo2-17
demo2-18
demo2-19
demo-0
demo-1
demo-2
demo-3
demo-4
demo-5
demo-6
demo-7
demo-8
demo-9
demo2-20
demo2-21
demo2-22
demo2-23
demo2-24
demo2-25
demo2-26
demo2-27
demo2-28
demo2-29
demo2-30
demo2-31
demo2-32
demo2-33
demo2-34
demo2-35
demo2-36
demo2-37
demo2-38
demo2-39