Python Day06

进程概念

  • 进程就是操作系统中执行的一个程序,操作系统以进程为单位分配存储空间
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

  1. Queue.empty():判断队列是否为空。

  2. ueue.full():判断是否满了。

  3. Queue.put(item, block=True, timeout=None): 往队列里放数据。

    • ) 如果满了的话,blocking = False 直接报 Full异常。
    • )如果blocking = True,就是等一会,timeout必须为 0 或正数。None为一直等下去,0为不等,正数n为等待n秒还不能存入,报Full异常。
    • )Queue.put_nowait(item):往队列里存放元素,不等待
  4. Queue.get(item, block=True, timeout=None): 从队列里取数据。

    • ) 如果为空的话,blocking = False 直接报 empty异常。
    • )如果blocking = True,就是等一会,timeout必须为 0 或正数。None为一直等下去,0为不等,正数n为等待n秒还不能读取,报empty异常。
    • )Queue.get_nowait(item):从队列里取元素,不等待
  5. 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 CType Python Type
bsigned char int
Bunsigned char int
cchar character
ddouble float
ffloat float
hsigned short int
Hunsigned short int
isigned int int
Iunsigned int long
lsigned long int
Lunsigned long long
uPy_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'}
"""
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值