多任务---进程、进程池

本文探讨了进程和线程在实现多任务中的角色。进程作为资源分配单位,多个进程可以并发执行,但资源消耗较大。线程则共享进程内存,提高并发效率。在Ubuntu中可以查看所有进程。通过队列实现多进程间的数据共享,如文件夹拷贝任务。然而,在Windows上尝试创建进程池时遇到问题,包括路径查找和进度条显示的挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现多任务的另一种形式
程序是可以运行的,运行起来叫做进程,能够分配各种资源。(网络、显卡、鼠标、键盘、蓝牙…)
程序只有一个,但是进程可以多个。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
使用进程实现多任务

import time
import multiprocessing

def test1():
    while True:
        print('----1-----')
        time.sleep(1)


def test2():
    while True:
        print('----2-----')
        time.sleep(1)


def main():

    p1 = multiprocessing.Process(target=test1)
    p2 = multiprocessing.Process(target=test2)
    p1.start()
    p2.start()

if __name__ == '__main__':
    main()

在这里插入图片描述
可以看出,进程和我们学过的线程 效果是一样的。
在ubuntu 中查看所有进程

ps -aux

在这里插入图片描述
进程 和 线程 都能实现多任务,但是进程占用的资源比较大。

进程和线程的区别:
在这里插入图片描述
线程不能独立执行,必须已存在进程中。
可以将进程理解为工厂中的一条流水线,而其中的线程就是这个流水线上的工人。
在这里插入图片描述
一个程序至少有一个进程,一个进程至少有一个线程。
线程的划分尺度小于进程,使得多线程程序的并发性高。
进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。比如:
在这里插入图片描述
网易云和天天静听 是两个进程,同时打开就是多进程,在每个进程中,既可以播放音乐,同时又能下载音乐,这就是多线程。

线程之间共享数据,但是进程是独立的,所以进程之间主需要通信。–队列

队列:先进先出–Queue
栈:先进后出

解耦:避免两个程序之间联系太过密切。

多进程之间通过Queue 来实现数据共享:

import multiprocessing


def download_from_web(q):
    '''下载数据'''
    data = [1, 2, 3]
    # 向队列中写诶数据
    for i in data:
        q.put(i)
    print('---下载器已经下载完了数据,并且写入队列中')


def analysis_data(q):
    '''数据处理'''

    waitting_data = list()
    # 从队列中获取数据
    while True:
        data = q.get()
        waitting_data.append(data)

        if q.empty():
            break
    # 模拟数据处理
    print(waitting_data)


def main():

    # 创建一个队列
    q = multiprocessing.Queue()

    p1 = multiprocessing.Process(target=download_from_web, args=(q,))
    p2 = multiprocessing.Process(target=analysis_data, args=(q,))
    p1.start()
    p2.start()

if __name__ == '__main__':
    main()

在这里插入图片描述
在这里插入图片描述
任务数确定,创建对应的进程就可以,当任务数不确定,创建进程池。
在这里插入图片描述
这个程序 ,我在windows 上的pycharm 没有实现。不知道为啥。
本应该的运行结果:
在这里插入图片描述

from multiprocessing import Pool
import os, time, random


def worker(msg):
    t_start = time.time()
    print('%s开始执行,进程号:%d' % (msg, os.getpgid()))
    # random.random() 随机生成0-1之间的浮点数
    time.sleep(random.random()*2)
    t_stop = time.time()
    print(msg, '执行完毕,耗时%0.2f' % (t_start - t_stop))

def main():
    po = Pool(3)  # 创建一个进程池,最大进程数3
    for i in range(0,10):
        # Pool().apply.async(要调用的目标,(传递给目标的参数元祖,))
        # 每次循环都会用空闲出来的子进程去调用目标
        po.apply_async(worker,(i,))

    print('----start---')
    po.close()  # 关闭进程池,关闭后po 不在接收新的请求
    po.join()  # 等待po 中所有子进程执行完成,必须放在close之后,保证主进程运行时间大于子进程。
    print('----end-----')


if __name__ == '__main__':
    main()

在这里插入图片描述
多任务文件夹拷贝:

import os
import multiprocessing


def copy_file(q, file_name, old_folder_name, new_folder_name):
    '''完成文件的复制'''
    old_f = open(old_folder_name + '/' + file_name, 'rb')  # 路径,用 / 连接
    content = old_f.read()
    old_f.close()

    new_f = open(new_folder_name + '/' + file_name, 'wb')
    new_f.write(content)
    new_f.close()

    # 如果拷贝完了文件,那么就向队列中写入一个消息,表示已经完成
    q.put(file_name)

def main():
    # 1. 获取用户要拷贝的文件夹的名字
    old_folder_name = input('请输入要复制的文件夹的名字:')

    # 2. 创建一个新的文件夹
    try:
        new_folder_mame = old_folder_name + '[复件]'
        os.mkdir(new_folder_mame)
    except:
        pass

    # 3. 获取文件夹中所有文件的名字 listdir()
    file_names = os.listdir(old_folder_name)
    # print(old_folder_name)

    # 4. 创建进程池
    po = multiprocessing.Pool(5)

    # 5. 创建一个队列
    q = multiprocessing.Manager().Queue()

    # 向进程池中添加 copy 文件的任务
    for file_name in file_names:
        po.apply_async(copy_file,args=(q, file_name, old_folder_name, new_folder_mame))

    po.close()
   # po.join()

    all_file_num = len(file_names)  # 测一下文件个数
    copy_num = 0
    while True:
        file_name = q.get()
        # print('已经完成拷贝: %s' % file_name)
        copy_num += 1
        print('拷贝的进度为 %.2f %%' % (copy_num * 100 / all_file_num),end='\r') # \r 表示一直都在顶行显示
        if copy_num >= all_file_num:
            break
        print()


if __name__ == '__main__':
    main()

在运行中遇到很多问题,

  1. 要复制的文件夹必须在工程下,否则找不到路径
  2. 要复制的文件夹中不能再包含文件夹,否则程序一直不结束。
    在这里插入图片描述
    但是,不成功的地方也有,想要在一行显示进度条,但是不知道为啥不成功。
    大概是这样的效果:进度从0变到100,只更新不换行。
    在这里插入图片描述

1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值