首页 > 系统相关 >python_进程与线程_多线程

python_进程与线程_多线程

时间:2024-07-24 11:24:49浏览次数:17  
标签:__ name python 进程 线程 time print 多线程

一、程序与进程的概念

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

相关文章

  • python_网络编程_socket
    一、网络编程的基本概念通信协议:internet协议,任何私有网络支持此协议,就可以接入互联网二、七层协议与四层协议从下到上分别是:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层三、掌握TCP、IP协议ip协议是整个TCP、IP协议族的核心IP地址就是会联网上计算......
  • 你能对 Python 类型注释进行模式匹配吗?
    你能在Python类型上进行模式匹配吗?我见过简单的例子:importbuiltinsmatchx:casebuiltins.str:print("matchedstr")casebuildins.int:print("matchedint")但我想在嵌套类型上进行模式匹配,比如Annotated[Optional[Literal["a",......
  • python Polars:替换嵌套列表的元素
    有谁知道是否可以有效地替换极坐标中嵌套列表的元素。例如:s=pl.Series('s',[[1,2,3],[3,4,5]])#replace3with10toget[[1,2,10],[10,4,5]]我已经尝试过s.to_frame().with_columns(pl.when(pl.col('s')==3)...)但是pl.when不喜欢List[bo......
  • Python 中的常量应该大写吗?
    在PEP8中,一般规则是在UPPER_CASE字符中声明常量。在现实生活中,可能有多种情况:#!envpythonDATABASE_HOST='localhost'app=Flask('myapp')base_two=partial(int,base=2)通常我们将字符串类型或数字类型变量视为不可变的,因此是常量,而不是对象或函数。问题是......
  • 多重处理会导致 Python 崩溃,并给出一个错误:调用 fork() 时可能已在另一个线程中进行
    我对Python比较陌生,并试图为我的for循环实现一个多处理模块。我在img_urls中存储了一个图像url数组,我需要下载并应用一些Google视觉。if__name__=='__main__':img_urls=[ALL_MY_Image_URLS]runAll(img_urls)print("---%sseconds---"%(......
  • Python编程时输入操作数错误
    我正在用Python编写下面的代码来模拟控制系统。但是,当我调试代码时,我面临以下问题:matmul:输入操作数1没有足够的维度(有0,gufunc核心,签名为(n?,k),(k,m?)->(n?,m?)需要1)文件“D:\ÁreadeTrabalho\GitHub\TCC\CódigosMarcela\SistemaSISO_tres_estados_new.py”,......
  • Python入门知识点 7--散列类型与字符编码
    1、初识散列类型(无序序列)数据类型分为3种:   前面已经学过了两种类型   1.数值类型:int/float/bool只能存储单个数据      2.序列类型:str/list/tuple,有序的存储多个数据--有序类型,有下标,可以进行索引切片步长操作          3.散列类型......
  • Python入门知识点 6--序列类型的方法
    1、初识序列类型方法序列类型的概念:数据的集合,在序列类型里面可以存放任意的数据也可以对数据进行更方便的操作这个操作就是叫增删改查(crud)(增加(Creat),读取查询(Retrieve),更新(Update),删除(Delete)几个单词的首字母简写)增删改查是操作数据最底层的操作(从本质......
  • Python项目流程图
    我有一个由多个文件夹组成的Python项目,每个文件夹包含多个脚本。我正在寻找一个Python库或软件/包,它们可以生成流程图,说明这些脚本如何互连并绘制出从开始到结束的整个过程。自动生成Python项目流程图确实是一个挑战,目前没有完美通用的解决方案。主要原因是:......
  • 使用 mypy 时Python中的继承和多态性不起作用
    我正在寻找用mypy做一些标准的多态性,我以前从未使用过它,而且到目前为止它并不直观。基类classContentPullOptions:passclassTool(Protocol):asyncdefpull_content(self,opts:ContentPullOptions)->str|Dict[str,Any]:...子类classGoogle......