多进程和多线程

多进程和多线程

多线程

import time
from datetime import datetime
from threading import Thread


# 进程默认有一个线程,这个线程叫主线程;其他的线程都叫子线程
# Python中的threading模块中Thread类的对象就是线程对象(程序中需要多少个线程就创建多少个Thread类或者它的子类的对象)
def download(name):
    print(f'{name}开始下载!{datetime.now()}')
    time.sleep(3)
    print(f'{name}下载结束!{datetime.now()}')


# 1.创建线程对象
# Thread(target=函数, args=参数)
# 函数    -   传一个函数,这个函数就是需要在子线程中调用的函数
# 参数    -   传一个元组,默认是();元组中的元素就是在调用函数的时候需要传递的实参
t1 = Thread(target=download, args=('海王',))
t2 = Thread(target=download, args=('触不可及',))
t3 = Thread(target=download, args=('星际穿越',))

# 2.启动线程    -   在子线程中执行任务
# 线程对象.start()
t1.start()
t2.start()
t1.join()
t2.join()
t3.start()

# 1.join的用法
"""
线程对象.join()
代码段

代码段会在线程对象对应的线程结束后执行
"""

f_names = ['海王', '触不可及', '星际穿越']

线程池

from threadpool import ThreadPool, makeRequests
import time
from datetime import datetime
from threading import current_thread, Thread
from queue import Queue

q = Queue()


def download(name):
    print(f'{name}开始下载!', datetime.now())
    print(current_thread())
    time.sleep(1)
    print(f'{name}下载结束!', datetime.now())
    q.put(name)


def save():
    print('============开始保存===========')
    num = 0
    while True:
        print('==保存数据的线程==', current_thread())
        result = q.get()
        if result == 'end':
            break
        print(f'=====保存{result}成功')


# 1.创建任务列表
# makeRequests(任务对应的函数,参数列表)
# 注意:
# 1)任务函数有且只有一个参数
# 2)参数列表中元素的个数决定了任务列表中任务的个数
tasks = makeRequests(download, [f'电影{x}' for x in range(100)])
# tasks2 = makeRequests(save, [0])
# print(tasks)
# 2.创建线程池对象
# ThreadPool(线程的数量)
pool = ThreadPool(10)


# 3.在线程池中添加任务
# 线程池对象.putRequest(任务对象)
for task in tasks:
    pool.putRequest(task)
# for task in tasks2:
#     pool.putRequest(task)
# 在一个独立线程中添加保存任务
t = Thread(target=save)
t.start()

# 4.执行和等待
pool.wait()
q.put('end')

线程之间的数据安全

lockRlock

使用方法

from threading import Thread, current_thread, Lock, RLock

"""
 1)保证一个数据对应一个锁对象
 锁对象 = Lock()
 2)线程在第一次操作数据前加锁
 锁对象.acquire()
 3)线程在结束数据操作后解锁
 锁对象.release()
"""
"""
Lock也可用这种方法
 1)保证一个数据对应一个锁对象
 锁对象 = RLock()
 2)将对数据进行操作的代码放到锁的范围内
 with 锁对象:
    操作数据的代码
"""
"""
这两种琐的主要区别是:RLock允许在同一线程中被多次acquire。而Lock却不允许这种情况。注意:如果使用RLock,那么acquire和release必须成对出现,即调用了n次acquire,必须调用n次的release才能真正释放所占用的琐。
"""
  

多进程

from multiprocessing import Process
import time
from datetime import datetime


# 多进程和多线程的区别:
# 多线程只是增加线程数量,不会增加运行内容(只是在车间中添加工人);多个线程可以修改同一个全局变量
# 多进程会增加线程数量,也会增加运行内容(添加新的车间,每个车间拥有一个工人);不能在一个中取修改另一个进程的数据

def download(name):
    print(f'{name}开始下载!', datetime.now())
    time.sleep(1)
    print(f'{name}下载结束!', datetime.now())


if __name__ == '__main__':
    # 1.创建进程对象
    p1 = Process(target=download, args=('让子弹飞',))
    p2 = Process(target=download, args=('赌神',))
    p3 = Process(target=download, args=('活着',))

    # 2.开始执行进程中的任务
    p1.start()
    p2.start()
    p3.start()

进程池

from multiprocessing import Pool
import time
from datetime import datetime
from threadpool import ThreadPool, makeRequests
from queue import Queue
from threading import current_thread


def download(name):
    print(f'{name}开始下载!')
    # print(current_thread())
    time.sleep(1)
    print(f'{name}下载结束!')


def download_movie_thread(num):
    # q = Queue()
    # q.put(num)
    # if q.qsize() == 10:
    tasks = makeRequests(download, num)
    pool1 = ThreadPool(10)
    for x in tasks:
        pool1.putRequest(x)
    pool1.wait()


if __name__ == '__main__':
    # 1.创建进程池
    # Pool(进程数量)
    list1 = [f'电影{x}' for x in range(200)]
    list2 = []
    for i in range(0, 200, 10):
        list2.append(list1[i:i + 10])
    start = time.time()
    pool = Pool(3)

    # 2.添加任务(任务添加完成后会自动启动)
    # 1)一次性添加多个任务
    # 进程池对象.map(函数,参数列表)
    # pool.map(download_movie_thread, [])
    # 2)一次添加一个任务
    pool.map(download_movie_thread, list2)
    # apply()   -   添加的任务和主进程中的任务同步执行
    # apply_async() -   添加的任务和主进程中的任务异步执行
    # pool.apply(download, ('肖申克的救赎',))

    # 3.关闭线程池
    # 进程池关闭后不能再往进程池中添加任务
    pool.close()

    # 4.等待
    pool.join()
    end = time.time()
    print('结束====================', end-start)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值