进程概念
- 进程就是操作系统中执行的一个程序,操作系统以进程为单位分配存储空间
import multiprocessing
#要对大量文件和大量路径进行操作,导入os包
import os
def info(title):
print(title)
print(__name__)
#获取进程id
print('Tom', os.getpid())
print('Sarry', os.getpid())
print('--------')
# 除了创建的子进程和子进程调用函数,其他的都是脚本主进程
if __name__ == "__main__":
# info('hello')
# 创建一个子进程调用函数
P = multiprocessing.Process(target=info,args=('hello python',))
#启动线程
P.start()
P.join()
# 若没有join则会独立运行
print('hello word')
"""
运行结果1:
hello python
__mp_main__
Tom 13572
Sarry 13572
--------
hello word
运行结果2:(若没有join)
hello word
hello python
__mp_main__
Tom 11500
Sarry 1150
"""
join
- . join(): 连接字符串数组。将字符串、元组、列表中的元素以指定的字符(分隔符)连接生成一个新的字符串
- os.path.join(): 将多个路径组合后返回
import multiprocessing
import os
import time
def info(title):
print(title)
time.sleep(2)
print(__name__)
print('Tom', os.getppid())
print('Sarry', os.getpid())
print('--------')
if __name__ == "__main__":
p1 = multiprocessing.Process(target=info,args=('A1',))
p2 = multiprocessing.Process(target=info, args=('A2',))
p3 = multiprocessing.Process(target=info, args=('A3',))
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
# 这里的join只是为了卡住主进程,使得三个进程都执行完毕再执行print
# 这里很重要,以后多进程扫描文件需要完全等待几个进程全部执行完毕在汇总
print('over')
'''
轮流执行
p1.start()
p1.join()
p2.start()
p2.join()
p3.start()
p3.join()
'''
"""
运行结果:
A2
A1
A3
__mp_main__
__mp_main__
Tom 1296
Sarry 8904
--------
Tom 1296
Sarry 7400
--------
__mp_main__
Tom 1296
Sarry 13424
--------
over
"""
Rlock(可重入锁)
- 在同一线程内,对RLock进行多次acquire()操作,程序不会阻塞。
- 多进程,并发,可能乱序并发执行(主要看系统如何处理),多进程加锁,挨个执行,也可能是乱序
# 进程同步
import os
import multiprocessing
import time
def showdata(lock, i):
with lock:
print(multiprocessing.current_process().name)
time.sleep(2)
print(i)
if __name__ == "__main__":
# 创建锁
lock = multiprocessing.RLock()
for num in range(10):
multiprocessing.Process(target=showdata, args=(lock, num)).start()
"""
运行结果:
Process-7
6
Process-9
8
Process-1
0
Process-3
2
Process-5
4
Process-6
5
Process-8
7
Process-4
3
Process-2
1
Process-10
9
"""
pipe(#进程通信)
import multiprocessing
import os
# conn表示管道类型
def func(conn):
# 收到的数据
print('func',os.getpid(), conn.recv())
# 发送的数据
conn.send(['a', 'b', 'c', 'd', 'e'])
# 关闭
conn.close()
if __name__ == "__main__":
# 创建一个管道,有两个口
conn_a, conn_b = multiprocessing.Pipe()
# 相当于在进程中conn_a.send(['a','b','c','d','e']),发送给conn_b
p = multiprocessing.Process(target=func, args=(conn_a,)).start()
# 发送数据给conn_a
conn_b.send([1, 2, 3, 4, 5, 6, 7])
print('mian',os.getpid(), conn_b.recv())
"""
运行结果:
func 516 [1, 2, 3, 4, 5, 6, 7]
mian 8 ['a', 'b', 'c', 'd', 'e']
"""
- 需求:A发送消息,B收到
import multiprocessing
def A(conn):
#收到的数据
print('A',conn.recv())
#关闭
#conn.close()
if __name__ == "__main__":
conn_a,conn_b = multiprocessing.Pipe()
p = multiprocessing.Process(target = A,args = (conn_a,))
p.start()
input_ = input('请输入要发送给B的内容:')
#发送数据给conn_a
conn_b.send(input_)
"""
运行结果:
请输入要发送给B的内容:Hello
A Hello
"""
全局变量不可以进程共享
import multiprocessing
import os
data = []
def List():
global data
data.append(2)
data.append(4)
data.append(5)
print('p',os.getpid(),data)
if __name__ == '__main__':
# 子进程
p = multiprocessing.Process(target=List,args=()).start()
# 脚本主进程
data.append('x')
data.append('y')
data.append('z')
print('main',os.getpid(),data)
"""
运行结果:
main 8404 ['x', 'y', 'z']
p 2832 [2, 4, 5]
"""
queue
-
Queue.empty():判断队列是否为空。
-
ueue.full():判断是否满了。
-
Queue.put(item, block=True, timeout=None): 往队列里放数据。
- ) 如果满了的话,blocking = False 直接报 Full异常。
- )如果blocking = True,就是等一会,timeout必须为 0 或正数。None为一直等下去,0为不等,正数n为等待n秒还不能存入,报Full异常。
- )Queue.put_nowait(item):往队列里存放元素,不等待
-
Queue.get(item, block=True, timeout=None): 从队列里取数据。
- ) 如果为空的话,blocking = False 直接报 empty异常。
- )如果blocking = True,就是等一会,timeout必须为 0 或正数。None为一直等下去,0为不等,正数n为等待n秒还不能读取,报empty异常。
- )Queue.get_nowait(item):从队列里取元素,不等待
-
Queue.join()一直阻塞直到队列中的所有元素都被取出和执行
未完成的个数,只要有元素添加到queue中就会增加。未完成的个数,只要消费者线程调用task_done()表明其被取走,其调用结束。当未完成任务的计数等于0,join()就会不阻塞
# 队列可以进程共享
import multiprocessing
import os
queue = multiprocessing.Queue()
# 注意队列只能单向,要么是父进程插入子进程取出,要么是子进程插入父进程取出
def func(in_):
print(os.getpid())
in_.put([1, 2, 3, 4]) # 子进程插入
if __name__ == '__main__':
print(os.getpid())
# queue.put(['a','b']) # 这里若是脚本父进程先插入了,子进程就没法再插入了
p = multiprocessing.Process(target=func, args=(queue,))
p.start()
print(queue.get()) # 脚本父进程取出
"""
运行结果:
8964
6560
[1, 2, 3, 4]
"""
queueplus
import multiprocessing
import os
queue = multiprocessing.Queue()
def adddata(queue, i): # 子进程调用的函数
queue.put(i)
print('put', os.getppid(), os.getpid(), i)
if __name__ == '__main__': # 脚本父进程
mylist = []
for i in range(10):
p = multiprocessing.Process(target=adddata, args=(queue, i)) # 子进程
p.start()
# print(queue.get())
mylist.append(queue.get()) # get拿不到东西会一直等待
"""
运行结果:
put 12608 15056 0
put 12608 11680 1
put 12608 13572 2
put 12608 13296 3
put 12608 11012 4
put 12608 6020 5
put 12608 12404 6
put 12608 12348 7
put 12608 8104 8
put 12608 12428 9
"""
进程数据共享
- Value(typecode_or_type, *args[, lock])
- Value函数返回一个shared memory包装类,其中包含一个ctypes对象
- typecode_or_type typecode列表如下:
Type code C | Type Python Type |
---|---|
b | signed char int |
B | unsigned char int |
c | char character |
d | double float |
f | float float |
h | signed short int |
H | unsigned short int |
i | signed int int |
I | unsigned int long |
l | signed long int |
L | unsigned long long |
u | Py_UNICODE Unicode character |
import multiprocessing
def func(num):
num.value = 10
if __name__ == '__main__':
# multiprocessing.Value可以在不同进程之间共享数据
num = multiprocessing.Value('d', 1) # double float
print(num.value) # 单单num返回的结果 Synchronized wrapper for c_double(1.0)
p = multiprocessing.Process(target=func, args=(num,))
p.start()
p.join()
print(num.value)
"""
运行结果:
1.0
10.0
"""
进程列表数组共享
import multiprocessing
def func(num):
num[2] = 9999
if __name__ == '__main__':
# 不同进程之间实现数组共享
num = multiprocessing.Array('i', [1, 2, 3, 4, 5, 6]) # i代表int类型
print(num[:])
p = multiprocessing.Process(target=func, args=(num,))
p.start()
p.join()
print(num[:])
"""
运行结果:
[1, 2, 3, 4, 5, 6]
[1, 2, 9999, 4, 5, 6]
"""
进程字典列表共享
import multiprocessing
def func(mydict, mylist):
mydict["玛卡"] = "baka"
mydict["依古"] = "bigu"
mylist.append(1)
mylist.append(2)
mylist.append(3)
if __name__ == "__main__":
# with multiprocessing.Manager() as MG:
# mydict=MG.dict()
# mylist=MG.list(range(5))
mydict = multiprocessing.Manager().dict()
# [0,1,2,3,4]
mylist = multiprocessing.Manager().list(range(5))
p = multiprocessing.Process(target=func, args=(mydict, mylist))
p.start()
p.join()
print(mylist)
print(mydict)
# print(list(range(5)))
"""
[0, 1, 2, 3, 4, 1, 2, 3]
{'玛卡': 'baka', '依古': 'bigu'}
"""