Skip to content

Commit 6fa8d38

Browse files
author
rongweihe
committed
Add python 多线程多进程
1 parent 0b0a6d6 commit 6fa8d38

28 files changed

+198
-0
lines changed
File renamed without changes.
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# 多进程
2+
3+
### 1、执行带有参数的任务+输出进程编号和父进程编号
4+
5+
```python
6+
'''
7+
Author: your name
8+
Date: 2021-08-13 13:18:17
9+
LastEditTime: 2021-08-13 13:24:24
10+
LastEditors: Please set LastEditors
11+
Description: In User Settings Edit
12+
FilePath: /spider/Python基础/多进程例子.py
13+
'''
14+
import multiprocessing
15+
import time
16+
import os
17+
18+
def sing(num,name):
19+
print("当前唱歌进程的编号",os.getpid(),os.getppid())
20+
for i in range(num):
21+
print(name)
22+
print("唱歌...")
23+
time.sleep(0.5)
24+
25+
def dance(num,name):
26+
print("当前跳舞进程的编号",os.getpid(),os.getppid())
27+
for i in range(num):
28+
print(name)
29+
print("跳舞...")
30+
time.sleep(0.5)
31+
32+
if __name__ == '__main__':
33+
print("主进程pid",os.getpid())
34+
sing_process = multiprocessing.Process(target=sing,args=(3,"hrw"))
35+
dance_process = multiprocessing.Process(target=dance,kwargs={"name":"hrw","num":3})
36+
37+
sing_process.start()
38+
dance_process.start()
39+
```
40+
41+
## 输出
42+
43+
```shell
44+
主进程pid 89134
45+
当前跳舞进程的编号 89138 89134
46+
hrw
47+
跳舞...
48+
当前唱歌进程的编号 89137 89134
49+
hrw
50+
唱歌...
51+
hrw
52+
hrw
53+
跳舞...
54+
唱歌...
55+
hrw
56+
hrw
57+
唱歌...
58+
跳舞...
59+
```
60+
61+
看输出,验证正确。
62+
63+
### 主进程和子进程区别
64+
65+
![](https://cdn.jsdelivr.net/gh/rongweihe/ImageHost01/gzh/multi01.png)
66+
67+
### 2、主进程退出会等待所有的子进程退出才退出
68+
69+
默认情况下,为了保护子进程能够正常执行,主进程会等待所有的子进程退出才退出。
70+
71+
那如果想要实现主进程退出之后子进程也退出,怎么做呢?
72+
73+
很简单,设置守护主进程。
74+
75+
```python
76+
'''
77+
Author: your name
78+
Date: 2021-08-13 13:18:17
79+
LastEditTime: 2021-08-14 15:29:38
80+
LastEditors: Please set LastEditors
81+
Description: In User Settings Edit
82+
FilePath: /spider/Python基础/设置守护主进程.py
83+
'''
84+
import multiprocessing
85+
import time
86+
import os
87+
88+
def sing():
89+
for i in range(10):
90+
print("唱歌...")
91+
time.sleep(0.5)
92+
93+
if __name__ == '__main__':
94+
print("主进程pid",os.getpid())
95+
sing_process = multiprocessing.Process(target=sing)
96+
#设置守护主进程 主进程退出之后不在执行子进程
97+
sing_process.daemon = True
98+
sing_process.start()
99+
time.sleep(1)
100+
print("主进程完成...")
101+
```
102+
103+
输出
104+
105+
```python
106+
主进程pid 94797
107+
唱歌...
108+
唱歌...
109+
主进程完成...
110+
```
111+
112+
### 3、多进程实现数据拷贝
113+
114+
```python
115+
'''
116+
Author: your name
117+
Date: 2021-08-13 13:18:17
118+
LastEditTime: 2021-08-14 16:01:23
119+
LastEditors: Please set LastEditors
120+
Description: In User Settings Edit
121+
FilePath: /spider/Python基础/多进程实现数据拷贝.py
122+
'''
123+
import multiprocessing
124+
import time
125+
import os
126+
127+
def copy_file(file_name, source_dir, dest_dir):
128+
#1. 拼接文件路径 和 目标文件路径
129+
source_path = source_dir + "/" + file_name
130+
dest_path = dest_dir + "/" + file_name
131+
132+
#2.打开源文件和目标文件
133+
with open(source_path,'rb') as source_file:
134+
with open(dest_path,'wb') as dest_file:
135+
#3. 循环读取源文件到目标路径
136+
#只要还能读到数据就一直读取 除非读不到数据了
137+
while True:
138+
data = source_file.read(1024)
139+
if data:
140+
dest_file.write(data)
141+
else:
142+
break
143+
144+
if __name__ == '__main__':
145+
#1. 定义源文件夹 和 目标文件夹
146+
source_dir = "/home/test1"
147+
dest_dir = "/home/test2"
148+
149+
#2. 创建目标文件夹
150+
try:
151+
os.mkdir(dest_dir)
152+
except:
153+
print("目标文件夹已经存在")
154+
155+
#3. 读取源文件夹列表
156+
file_list = os.listdir(source_dir)
157+
158+
#4. 遍历文件列表进行拷贝
159+
for file_name in file_list:
160+
sub_process = multiprocessing.Process(target=copy_file,
161+
args=(file_name, source_dir, dest_dir))
162+
sub_process.start()
163+
print("主进程完成...")
164+
```
165+
166+
# 多线程
167+
168+
- 多线程是 Python 程序中是实现多任务的一种方式。
169+
- 线程是程序执行的最小单元。
170+
- 同属一个进程的多个线程共享进程所有的全部资源。
171+
172+
**线程执行带有参数的任务**
173+
174+
- args:以元祖的方式给执行任务传参。
175+
- Kwargs:以字典形式给执行任务传参。
176+
177+
**两种方式设置守护主线程**
178+
179+
```python
180+
sing_thread.setDaemon(True) #调用函数设置守护主线程
181+
sing_thread = threading.Thread(target=sing, daemon=True) #创建子线程设置
182+
```
183+
184+
**多线程之间执行是无序的,是 CPU 调度的。**
185+
186+
多线程实现数据的拷贝区别只在于修改一行代码:
187+
188+
```python
189+
sub_thread = threading.Thread(target=copy_file,
190+
args=(file_name, source_dir, dest_dir))
191+
sub_thread.start()
192+
```
193+
194+
**注意点:**
195+
196+
- 知识点一:当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流的最小单元,当设置多线程时,主线程会创建多个子线程,在 python 中,默认情况下(其实就是 setDaemon(False)),主线程执行完自己的任务以后,就退出了,此时子线程会继续执行自己的任务,直到自己的任务结束。
197+
- 知识点二:当我们使用 setDaemon(True) 方法,设置子线程为守护线程时,主线程一旦执行结束,则全部线程全部被终止执行,可能出现的情况就是,子线程的任务还没有完全执行结束,就被迫停止。
198+
- 知识点三:此时 join 的作用就凸显出来了,join 所完成的工作就是线程同步,即主线程任务结束之后,进入阻塞状态,一直等待其他的子线程执行结束之后,主线程在终止。

0 commit comments

Comments
 (0)