Python并发编程基础 №② 进程 进程间的数据隔离 守护进程 进程锁

1、进程的常规使用

 1 import time
 2 from multiprocessing import Process
 3 
 4 
 5 def func(arg1):
 6     print('func is running, arg1 is:  ', arg1)
 7     time.sleep(2)
 8     print('func continue running!')
 9 
10 
11 if __name__ == '__main__': # windows中运行
12     p = Process(target=func, args=('name',))
13     p.start()
14     print('main process is running here!')

2、进程中的方法:join

 1 import os, time
 2 from multiprocessing import Process
 3 
 4 
 5 def func():
 6     print('子进程%s在运行'%os.getpid())
 7     time.sleep(1)
 8     print('子进程%s继续在运行' % os.getpid())
 9 
10 
11 if __name__ == '__main__':
12     print('主进程:', os.getpid(), '在运行!')
13     p = Process(target=func)
14     p.start()
15 
16     # 是感知一个子进程的结束
17     p.join()  # 将异步变同步,让主进程等待该子进程运行,直到结束。
18 
19     print('====== : 运行完了')
View Code

 

3、生成多个进程的例子,并使用join

 1 import os
 2 from multiprocessing import Process
 3 
 4 
 5 def write(filename, content):
 6     print('it is writing', os.getpid())
 7     with open(filename, 'w') as f:
 8         f.write(content * 10 * '*')
 9 
10 
11 if __name__ == '__main__':
12 
13     p_li = []
14     for i in range(10):
15         p = Process(target=write, args=('file_no%d'%i, i))
16         p_li.append(p)
17         p.start()
18 
19     [p.join() for p in p_li]  # 等待所有的进程运行完
20     print(os.listdir(os.getcwd()))  # 查看当前目录下所有的子目录名称,是一个列表。
21     print([ i for i in os.walk(os.getcwd())])  # 列表推导式,列表中含元组  #[('D:\\python_bases\\day36', [], todo 是上面的列表
22     print('主进程:', os.getpid(), '马上结束运行。。。。')
View Code

4、使用继承来使用进程

 1 from multiprocessing import Process
 2 import os
 3 
 4 
 5 class MyProcess(Process):
 6     """
 7     定义自己的额进程类,继承Process
 8     如果想实现初始化方法,必须带上Process的初始化方法
 9     """
10     def __init__(self, arg1, arg2):
11         super().__init__()  # 必须加,否则报错
12         self.arg1 = arg1
13         self.arg2 = arg2
14 
15     def run(self):
16         print("进程开启,id为:",os.getpid(),self.arg1, self.arg2)
17 
18 
19 if __name__ == '__main__':
20     print('主线程的id:', os.getpid())
21     mp1 = MyProcess(1, 2)
22     mp1.start()  # 如果run就和主进程id一样了!
23 
24     mp2 = MyProcess(3, 4)
25     mp2.start()
View Code

5、进程间的数据隔离问题

 1 import os
 2 from multiprocessing import Process
 3 
 4 n = 1000
 5 
 6 
 7 def show_data_independ(num):
 8     """
 9     演示进程间的数据隔离
10     :param num: n
11     :return: None
12     """
13     global n         # 声明了一个全局变量
14     #n = 10           # 重新定义了一个n
15     print('主进程传递过的n的值是:', num)
16     print('子进程中的n的值是:', n)
17 
18 
19 if __name__ == '__main__':
20     n = 100
21     p = Process(target=show_data_independ, args=(n,))
22     p.start()
23     p.join()
24     print(os.getpid(), n)
View Code

6、守护进程的开启

 1 import os, time
 2 from multiprocessing import Process
 3 
 4 
 5 def process_son_run():
 6     """
 7     非守护进程演示
 8     主进程已经结束运行,但是其子进程还在继续运行,这我默认状态
 9     :return:
10     """
11     while 1:
12         time.sleep(0.2)
13         print('子进程%s正在运行。。。。。。'%os.getpid())
14 
15 def son_process_walk():
16     print('son_process_walk   started')
17     time.sleep(8)
18     print('son_process_walk   finished')
19 
20 
21 if __name__ == '__main__':
22 
23     p = Process(target=process_son_run)
24 
25     # 必须在start前,如果开启,开启守护进程!(即主进程关闭则子进程一起关闭)
26     p.daemon = True
27     p.start()
28 
29     p2 = Process(target=son_process_walk)
30     p2.start()
31     p2.terminate()    # 结束一个子进程
32     print(p.name, p.pid)  # 不是马上结束,需要一个过程! Process-1 13068
33     time.sleep(1)
34     print(p2.is_alive())   # 检验一个进程是否还活着
35     print('主进程结束运行了!')
36 
37 # 守护进程 会 随着 主进程的代码执行完毕 而 结束
38 # 在主进程内结束一个子进程 p.terminate()
39     #  结束一个进程不是在执行方法之后立即生效,需要一个操作系统响应的过程
40 # 检验一个进程是否活着的状态 p.is_alive()
41 # p.name p.pid 这个进程的名字和进程号
View Code

7、进程锁的演示

 1 import time,os,json
 2 from multiprocessing import Process, Lock
 3 
 4 '''
 5 模拟网络购票:
 6 有网络延时的情况
 7 '''
 8 
 9 
10 def look_left(i):
11     """
12     看还剩多少票
13     :return:
14     """
15     with open('ticket') as f:
16         dic = json.load(f)
17         print('到杭州的火车票还剩%s张!'%dic['left'])
18 
19 
20 def buy(i, lock):
21     # lock.acquire()
22     time.sleep(i * 1)
23     # time.sleep(1)   如果等待时间太短,都会买到票,没法子,cpu6核的!
24     with open('ticket') as f:
25         dic = json.load(f)
26 
27     if dic['left'] > 0:
28         print('\033[31m购买者%s买到票了\033[0m!' % i)
29         dic['left'] -= 1
30     else:
31         print('\033[32m购买者%s没买到票了\033[0m!' % i)
32 
33     time.sleep(2)
34     with open('ticket', 'w') as f:
35         json.dump(dic, f)
36     # lock.release()
37 if __name__ == '__main__':
38 
39     # for i in range(10):
40     #    p = Process(target=look_left, args=(i,))
41     #    p.start()
42     lock = Lock()
43 
44     for i in range(10):
45         Process(target=buy, args=(i, lock)).start()
46 
47 
48 # 没加锁前:1张票有三个人抢到
49 # todo 购买者0买到票了!
50 # todo 购买者1买到票了!
51 # todo 购买者2买到票了!
52 '''
53 购买者3没买到票了!
54 购买者4没买到票了!
55 购买者5没买到票了!
56 购买者6没买到票了!
57 购买者7没买到票了!
58 购买者8没买到票了!
59 购买者9没买到票了!
60 '''
View Code

9、sock中server端并发提供服务

 server端的代码:

 1 import socket
 2 from multiprocessing import Process
 3 
 4 
 5 def serve(conn):
 6     msg = conn.recv(1024).decode('utf-8')
 7     print(msg)
 8     conn.close()
 9 
10 
11 if __name__ == '__main__':
12 
13     sk = socket.socket()
14     sk.bind(('127.0.0.1', 8888))
15     sk.listen()
16     # todo 如果在这sk.accept() 会将cpu资源耗尽!!!
17     try:
18         while True:
19             conn, addr = sk.accept()
20             conn.send('你好吗?'.encode('utf-8'))
21             Process(target=serve, args=(conn,)).start()
22     except:
23         sk.close()
View Code

client端的代码:

 1 import socket
 2 
 3 sk = socket.socket()
 4 sk.connect(('127.0.0.1', 8888))
 5 
 6 msg = sk.recv(1024).decode('utf-8')
 7 print(msg)
 8 
 9 ipt = input('>>>').encode('utf-8')
10 sk.send(ipt)
11 
12 sk.close()
View Code
posted @ 2019-12-25 22:04  四方游览  阅读(144)  评论(0)    收藏  举报