一、程序与进程的概念
1、进程:
指启动后的程序,系统会为进程分配内存空间
二、创建进程的方式
1、第一种创建进程的方式
process(group = None,target,name,args,kwargs)
-
group:表示分组,实际上不使用,默认为None即可
-
target:表示子进程要执行的任务,支持函数名
-
name:表示子进程的名称
-
args:表示调用的函数的位置参数,以元组的形式进行传递
-
kwargs:表示调用函数的关键字参数,以字典的形式进行传递
# haha
# time:2024/7/1 14:04
import time
from multiprocessing import Process
import os
def test():
print(f'我的子进程是:{os.getpid()},我的父进程是:{os.getppid()}')
time.sleep(1)
def test1(name):
print(f'我的子进程是:{os.getpid()},我的父进程是:{os.getppid()}-----{name}')
time.sleep(1)
def test2(name):
print(f'我的子进程是:{os.getpid()},我的父进程是:{os.getppid()}------{name}')
time.sleep(1)
if __name__ == '__main__':
print('主进程开始执行')
lst = []
for i in range(5):
#创建子进程
p = Process(target=test)
#启动子进程
p.start()
#启动的进程添加到列表中
lst.append(p)
p1 = Process(target=test1,args=('xxxx',))
p2 = Process(target=test2, args=('nnnn',))
p1.start()
p2.start()
print(p1.name,"进程是否正在运行:",p1.is_alive())
print(p2.name, "进程是否正在运行:", p2.is_alive())
print(p1.name,"pid: ",p1.pid)
print(p2.name, "pid: ", p2.pid)
p1.join() #主进程需要等待p1执行结束,阻塞的主进程
p2.join() #主进程要等待p2 执行结束
print(p1.name, "进程是否正在运行:", p1.is_alive())
print(p2.name, "进程是否正在运行:", p2.is_alive())
#遍历lst,列表中的5个子进程
for i in lst: #i 的数据类型是 process 类型
i.join() #阻塞主进程
print("主进程执行结束")
import os
import time
from multiprocessing import Process
def test1(name):
print(f'我的子进程是:{os.getpid()},我的父进程是:{os.getppid()}-----{name}')
time.sleep(1)
def test2(name):
print(f'我的子进程是:{os.getpid()},我的父进程是:{os.getppid()}------{name}')
time.sleep(1)
if __name__ == '__main__':
print("主进程开始执行")
for i in range(5):
p1 = Process(target = test1,args=('hhhh',)) #没有给参数,不会执行自己编写的函数中的代码,会调用执行process类中的run方法
p2 = Process(target = test2,args=('xxxxxx',))
p1.start() #调用process中的run方法去执行
p2.start() #如果指定了target参数就会target指定的函数去运行
#终止进程
p1.terminate()
p2.terminate()
print("主进程结束")
2、第二种创建子进程的方式
class 子进程(Process):
pass
#自定义一个类
class SubProcess(Process):
#编写初始化方法:
def __init__(self,name):
#调用父类中的方法
super().__init__()
self.name = name
#重写父类中的run方法
def run(self) -> None:
print(f'子进程的名称{self.name},PID:{os.getpid()},父进程:{os.getppid()}')
if __name__ == '__main__':
print('父进程开始执行')
lst =[]
for i in range(5):
p1 = SubProcess('i')
p1.start()
lst.append(p1)
for i in lst:
i.join()
print('父进程结束')
3、进程池的使用 pool
进程池:创建一个进程池,并设置进程池中最大的进程数量。假设进程池中的最大进程数为3,现在有10个任务需要执行,那么进程池一次可以执行3个任务,4次即可完成全部任务的执行。
语法结构:进程池对象 = Pool(N)
# haha
# time:2024/7/1 16:18
from multiprocessing import Process, Pool
import time,os
#编写任务
def task(name):
print(f"子进程的PID:{os.getpid()},执行的任务:{name}")
time.sleep(2)
if __name__ == '__main__':
#主进程
start = time.time()
print("父进程开始执行")
#创建进程池
p = Pool(3) #一次可以执行3个任务
for i in range(10):
#以非堵塞的方式进行
p.apply_async(func = task,args=(i,))
p.close() #关闭父进程,不在接受新任务
p.join() #阻塞父进程,等待所有的子进程执行完毕之后,才会执行父进程中的代码
print("父进程结束")
print(time.time() - start)
4、并发和并行
并发:多个事件在同一个时间间隔内发生
并行:多个事件在同一时刻发生
三、进程之间的通信
各个进程之间的数据是没有进行共享的
a = 100
def add():
print("子进程1开始运行")
global a
a += 30
print(f'a 的值是:{a}')
time.sleep(1)
def delet():
print("子进程2开始运行")
global a
a -= 30
print(f'a 的值是:{a}')
time.sleep(1)
if __name__ == '__main__':
print("主进程开始运行:")
p1 = Process(target= add)
p2 = Process(target= delet)
p1.start()
p2.start()
p1.join()
p2.join()
p1.close()
p2.close()
print("主程序运行结束")
print(a)
'''
主进程开始运行:
子进程1开始运行
a 的值是:130
子进程2开始运行
a 的值是:70
主程序运行结束
100
'''
1、队列(实现进程之间的数据共享)
队列:先进先出
创建队列的语法结构:队列对象 = Queue(N)
# haha
# time:2024/7/1 16:53
from queue import Queue
if __name__ == '__main__':
#创建一个队列
q = Queue(4) #最多可以放入4条信息
print('队列是否为空:',q.empty())
print('队列是否为满:',q.full())
q.put('hello')
q.put('world')
q.put_nowait('00000') #无视容量,就一直往里面加入元素
print("队列中有多少条信息:",q.qsize())
print('队列是否为空:',q.empty())
print('队列是否为满:',q.full())
while(not q.empty()):
data = q.get()
print(data)
print('队列是否为空:', q.empty())
print('队列是否为满:', q.full())
2、使用队列实现队列的通信
# haha
# time:2024/7/1 17:21
import os
import time
from multiprocessing import Process,Queue
a = 100
def write(q):
global a
if not q.full():
for i in range(6):
a -= 10
q.put(a)
print(f"a 入队时候的值:{a}")
def read(q):
time.sleep(1)
global a
while(not q.empty()):
print(f"a 出队时候的值:{q.get()}")
if __name__ == '__main__':
print("父进程开始执行")
q = Queue()
p1 = Process(target=write,args=(q,))
p2 = Process(target=read, args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
print("父进程结束执行")
print(f"a 的值为:{a}")
四、进程与线程
1、线程
线程是CPU可执行的最小单位,被包含在进程中,是进程中实际的运行单位。一个进程中可以拥有多个线程并发执行,每个线程并行执行不同的任务。
2、函数式创建线程的语法结构:
-
t = Thread(group,target,name,args,kwargs)
-
group:创建线程对象的进程组
-
target:创建的线程对象所要执行的目标函数
-
name:创建线程对象的名称,默认为:Tread-n
-
args:用元祖以位置参数的形式传入targt对应函数的参数
-
kwargs:用字典以关键字参数的形式传入target对应函数的参数
五、创建线程的方式
1、函数方式创建线程的方式
# haha
# time:2024/7/6 15:44
# 线程
import threading
from threading import Thread
import time
# 编写程序
def test():
for i in range(3):
time.sleep(1)
print(f"线程:{threading.current_thread().name}正在执行{i}")
if __name__ == '__main__':
start = time.time()
print("主线程开始执行")
# 线程
lst = [Thread(target=test) for i in range(2)]
for item in lst: #item 是thread 类型
#启动线程
item.start()
for item in lst:
item.join()
print(f"一个耗时:{time.time()-start}")
'''
三个线程并行执行的技术:主线程负责执行 main 的代码,thread——1线程执行三次循环
thread-2线程执行三次循环
\主线程开始执行
线程:Thread-2 (test)正在执行0
线程:Thread-1 (test)正在执行0
线程:Thread-2 (test)正在执行1
线程:Thread-1 (test)正在执行1
线程:Thread-2 (test)正在执行2
线程:Thread-1 (test)正在执行2
一个耗时:3.0110058784484863
'''
2、使用thread子类创建线程的操作
1)自定义类继承threading 模块下的thread类
2)实现run方法
class SubThread(Thread):
def run(self) -> None:
for i in range(3):
time.sleep(2)
print(f"继承线程:{threading.current_thread().name}正在执行{i}")
if __name__ == '__main__':
start = time.time()
print("主线程开始执行")
# 继承式创建线程
lst1 = [SubThread() for i in range(2)]
for a in lst1:
a.start()
for item in lst1:
item.join()
print(f"继承一共耗时:{time.time() - start}")
print("主线程执行完毕")
'''
主线程开始执行
继承线程:Thread-2正在执行0
继承线程:Thread-1正在执行0
继承线程:Thread-2正在执行1
继承线程:Thread-1正在执行1
继承线程:Thread-2正在执行2
继承线程:Thread-1正在执行2
继承一共耗时:6.019787788391113
主线程执行完毕
'''
六、线程之间的通信方式
线程之间的数据是可以共享
a = 100
def add():
print("加线程开始执行")
global a
a += 30
print(f"a 的值为:{a}")
print("加线程执行结束")
def delete():
print("减线程开始执行")
global a
a -= 50
print(f"a 的值为:{a}")
print("减线程执行结束")
if __name__ == '__main__':
start = time.time()
print("主线程开始执行")
print(f"a 的值为{a}")
#线程中的线程数据是否共享
t1 = Thread(target= add)
t2 = Thread(target=delete)
t1.start()
t2.start()
t1.join() #阻塞主进程的
t2.join()
print("主线程执行结束")
print(f"a 的值为{a}")
'''主线程开始执行
a 的值为100
加线程开始执行
a 的值为:130
加线程执行结束
减线程开始执行
a 的值为:80
减线程执行结束
主线程执行结束
a 的值为80
'''
解决线程共享数据时出现的安全问题
lock_obj = threading.Lock()
ticket = 50
def sale_tickets():
print("开始卖票")
global ticket
for i in range(100):
lock_obj.acquire() #进行上锁
if(ticket > 0):
print(f"可以买票,{threading.current_thread().name}正在出售第{ticket}张票")
ticket -= 1
lock_obj.release() #释放锁
time.sleep(1)
if __name__ == '__main__':
start = time.time()
print("主线程开始执行")
#解决多线程共享数据时出现不安全的问题
#创建3个线程,代表3个窗口正在买票
for i in range(3):
t = Thread(target= sale_tickets)
t.start()# 启动线程
七、生产者和消费者之间的关系
#生产者和消费者问题
class produce(Thread):
def __init__(self,name,queue):
Thread.__init__(self,name = name)
self.queue = queue
def run(self) -> None:
for i in range(1,6):
print(f"{self.name}将产品{i}放入队列")
self.queue.put(i)
time.sleep(1)
print("生产者完成所有数据存放")
class customer(Thread):
def __init__(self,name,queue):
Thread.__init__(self,name = name)
self.queue = queue
def run(self) -> None:
for i in range(1,6):
print(f"{self.name}将产品{i}拿出队列")
value = self.queue.get()
print(f"取出的数据是{value}")
time.sleep(1)
print("消费者完成所有数据接收")
if __name__ == '__main__':
start = time.time()
print("主线程开始执行")
#生产者消费者问题
queue = Queue()
#创建生产者线程
p = produce('produce',queue)
#创建消费者线程
q = customer('customer',queue)
#启动线程
p.start()
q.start()
p.join()
q.join()
print("消费者问题结束")
标签:__,name,python,进程,线程,time,print,多线程
From: https://blog.csdn.net/qq_53066304/article/details/140658078