并发编程-进程

2019-10-22  本文已影响0人  Yanl__

进程的特点

1.开启多进程

两种方式。

# 方式一
from multiprocessing import Process
import time
import os

def func(args, args2):
    print(args, args2)
    time.sleep(1)
    print('子进程:', os.getpid())
    print('子进程的父进程:', os.getppid())
    print('func')


# 开启一个进程
p = Process(target=func, args=('参数一', '参数二'))  # register, p is a process object
p.start()  # start
print('*'*10)
print('父进程:', os.getpid())  # 查看当前进程的进程号
print('父进程的父进程:', os.getppid())  # 查看当前进程的父进程
# 输出结果:
# **********
# 父进程: 7207
# 父进程的父进程: 1114
# 参数一 参数二
# 子进程: 7208
# 子进程的父进程: 7207
# func
# 方式二:
import os
from multiprocessing import Process

class MyProcess(Process):
    def run(self) -> None:
        print(self.pid)
        print(self.name)
        print('子进程的id', os.getpid())


print('主进程的id:', os.getpid())
p1 = MyProcess()
p1.start()
p2 = MyProcess()
p2.start()
# 方式二:(能传参)
# --> 通过 __init__
from multiprocessing import Process
import os


class MyProcess(Process):
    def __init__(self, arg1, arg2):  # 继承了Process, __init__也要继承父类的__init__
        super().__init__()
        self.arg1 = arg1
        self.arg2 = arg2

    def run(self) -> None:
        print(self.pid)  # 都是在父类Process中init方法中就有的。
        print(self.name)  # 都是在父类Process中init方法中就有的。
        print(self.arg1)


print('主进程的id:', os.getpid())
p1 = MyProcess(1, 3)
p1.start()

2.多进程的join方法

join方法:p.join() 是感知一个子进程的结束,将异步的程序改为同步

from multiprocessing import Process
import os

def func(filename, content):
    with open(filename, 'w') as f:
        f.write(content)

# 开启十个进程,同时开始写,等待全部写完后,展示文件夹中的所有文件
p_list = []
for i in range(10):
    p = Process(target=func, args=('info%s'%i, 'content%s'%i))
    p_list.append(p)
    p.start()
[p.join() for p in p_list]  # 之前的所有进程必须在这里执行完,才会执行下面的代码
print([i for i in os.walk('/Users/yanl/PycharmProjects/FullStack/并发编程')])

3.多进程之间的数据隔离问题

from multiprocessing import Process
import os


def func():
    global n
    n = 0
    print('子进程id:', os.getpid(), 'n=', n)

n = 100
p = Process(target=func)
p.start()
print('n=', n)

输出结果:
n= 100
子进程id: 7490 n= 0

子进程中更改了全局变量,并不能影响父进程中全局变量的值。进程之间的数据,不通过特殊手段是不能互通的。

4.使用多线程实现socket服务端的并发效果

server端

import socket
from multiprocessing import Process


def server(conn):
    conn.send(('hello').encode('utf-8'))
    msg = conn.recv(1024).decode('utf-8')
    print(msg)
    conn.close()


sk = socket.socket()
sk.bind(('127.0.0.1', 8080))
sk.listen()
while True:
    conn, addr = sk.accept()  # 收到一个连接,就开启一个进程。
    p = Process(target=server, args=(conn, ))
    p.start()

sk.close()

client端

import socket

sk = socket.socket()
sk.connect(('127.0.0.1', 8080))

msg = sk.recv(1024).decode('utf-8')
print(msg)
sendmsg = input('>>>').encode('utf-8')
sk.send(sendmsg)

sk.close()

5.守护进程

守护进程会随着主进程的代码执行完毕而结束。(是主进程的代码 不看其他子进程的执行时间 )
用法:在p.start()之前添加代码p.daemon=True

from multiprocessing import Process
import time


def func():
    while True:
        time.sleep(0.2)
        print('func 进程还在运行')


p = Process(target=func)
p.daemon = True  # 将子进程设置为守护进程
p.start()
i = 0
while i < 5:
    print('主进程还在运行')
    time.sleep(0.3)
    i += 1

运行结果:
主进程还在运行
主进程还在运行
func 进程还在运行
主进程还在运行
主进程还在运行
func 进程还在运行
主进程还在运行 

当有多个子进程时,守护进程func在主进程代码执行完毕后马上结束,并不等待其他子进程func2执行完。代码如下:

# 多个子进程
from multiprocessing import Process
import time


def func():
    while True:
        time.sleep(0.2)
        print('func 进程还在运行')


def func2():
    time.sleep(6)
    print('func2 刚刚执行完')


p = Process(target=func)
p.daemon = True  # 将子进程设置为守护进程
p.start()
p2 = Process(target=func2).start()

i = 0
while i < 5:
    print('主进程还在运行')
    time.sleep(0.3)
    i += 1

other

p = Process(target=func)
p.join()  # p.join() 是感知一个子进程的结束,将异步的程序改为同步
p.terminate()  # 结束该子进程
p.is_alive()  # 检查该进程是否还活着。真则返回True
p.name  # 返回该进程的名字
p.pid  # 返回该进程的进程号
上一篇 下一篇

猜你喜欢

热点阅读