기존 프로그래밍의 단점
기존 프로그래밍의 단점:
# 必须按照顺序执行,多个任务无法同时在还行
import time
def sing():
for i in range(5):
print("sing: hero")
time.sleep(1) # 每唱一次,等1秒再唱
def dance():
for i in range(5):
print("dance: swan")
time.sleep(1) # 每唱一次,等1秒再跳
def main():
sing()
dance()
if __name__ == "__main__":
main()
두 가지 작업에 소요되는 시간은 10초인데, 춤과 노래를 동시에 하고 싶다면, 사실 가장 긴 작업을 완료해야 두 가지 작업을 완료할 수 있습니다.
다중 프로세스, 다중 스레드, 코루틴 등과 같은 다중 작업 프로그래밍을 구현하는 방법에는 여러 가지가 있습니다.
2. 다중 작업을 달성하기 위해 다중 프로세스 방법을 사용합니다.
# 必须按照顺序执行,多个任务无法同时在还行
import time
import multiprocessing
def sing():
for i in range(5):
print("sing: hero")
time.sleep(1) # 每唱一次,等1秒再唱
def dance():
for i in range(5):
print("dance: swan")
time.sleep(1) # 每唱一次,等1秒再跳
def main():
p1 = multiprocessing.Process(target=sing)
p2 = multiprocessing.Process(target=dance)
p1.start()
p2.start()
if __name__ == "__main__":
main()
세 가지 프로세스의 일부 작업
명령어를 통해 htop
자세한 프로세스 목록을 볼 수 있습니다 .
참고: kill -9 pid
메인 프로세스를 종료한 후에도 하위 프로세스는 종료되지 않습니다. 이때 이 명령의 신호가 종료 작업을 수행하기 위해 메인 프로세스로 전송되므로 명령줄이 정상적으로 종료될 수 없습니다. 프로세스에 상위 프로세스가 없습니다. , 고아 프로세스가 되었으며 나중에 init 프로세스에 의해 채택되었습니다. 즉, 기본 프로세스를 종료한 후 하위 프로세스의 상위 프로세스를 init 프로세스라고 합니다.
를 통해 os.getpid()
현재 프로세스의 pid와 os.getppid()
상위 프로세스의 id를 얻을 수 있습니다.
4가지 프로세스 간 통신
프로세스는 독립적인 애플리케이션이기 때문에 서로 직접 통신할 수 없습니다.
프로세스 간 통신을 달성하기 위한 일반적인 방법에는 소켓 등이 포함됩니다. Python에서는 대기열 방법을 사용하여 다음을 달성할 수 있습니다.
queue = multiprocessing.Queue(3)
queue.put("111")
queue.put(222)
# 取数据
res = queue.get()
print(res)
# 判断: q.full() q.empty()
5개의 프로세스 풀
p = multiprocessing.Pool(3)
멀티태스킹을 위한 6가지 멀티스레딩 방법
import time
import threading
def sing():
for i in range(5):
print("sing: hero")
time.sleep(1) # 每唱一次,等1秒再唱
def dance():
for i in range(5):
print("dance: swan")
time.sleep(1) # 每唱一次,等1秒再跳
def main():
t1 = threading.Thread(target=sing) # 创建一个线程对象
t2 = threading.Thread(target=dance) # 创建一个线程对象
t1.start() # 开启线程
t2.start() # 开启线程
if __name__ == "__main__":
main()
세븐스레드 관련 API
threading.Thread()
스레드를 생성 하고 threading.enumerate()
현재의 모든 스레드를 볼 수 있습니다.
import time
import threading
def sing():
for i in range(5):
print("sing: hero")
time.sleep(1) # 每唱一次,等1秒再唱
def dance():
for i in range(5):
print("dance: swan")
time.sleep(1) # 每唱一次,等1秒再跳
def main():
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
t1.start()
t2.start()
while True:
length = len(threading.enumerate())
print("当前线程数为:%d" % length)
if length <= 1:
break
time.sleep(0.5)
if __name__ == "__main__":
main()
8. 동기화와 교착상태
스레드는 전역 변수를 공유하므로 데이터 혼란이 발생합니다.
import time
import threading
# 定义共享的全局变量
num = 0
def add100():
global num
for i in range(100000):
num = num + 0.00001
def add1000():
global num
for i in range(100000):
num = num + 1000
def main():
t1 = threading.Thread(target=add100)
t2 = threading.Thread(target=add1000)
t1.start()
t2.start()
time.sleep(5)
print(num) # 每次输出的结果是不相同的
if __name__ == "__main__":
main()
동기화를 달성하기 위해 뮤텍스 잠금을 사용하는 솔루션:
import time
import threading
# 定义共享的全局变量
num = 0
def add100():
global num
mutex.acquire() # 加锁:若已经加锁,则会直到锁被揭开
for i in range(100000):
num = num + 0.00001
mutex.release() # 解锁
def add1000():
global num
mutex.acquire() # 加锁:若已经加锁,则会直到锁被揭开
for i in range(100000):
num = num + 1000
mutex.release() # 解锁
# 创建互斥锁,默认不会上锁
mutex = threading.Lock()
def main():
t1 = threading.Thread(target=add100)
t2 = threading.Thread(target=add1000)
t1.start()
t2.start()
time.sleep(5)
print(num) # 100000001.0 永远不会变
if __name__ == "__main__":
main()