python第二十七天

本文详细探讨了Python中的多线程概念,包括如何创建和管理线程,以及线程间的同步。此外,还深入介绍了队列(Queue)数据结构在多线程环境中的使用,阐述了其在并发编程中的重要角色,帮助读者理解如何有效地利用队列进行任务调度和通信。
摘要由CSDN通过智能技术生成
from threading import Thread, current_thread
import time

# 1.多个线程可以直接操作同一个进程中的同一个数据
num = 200
print('定义:', current_thread())


def add_num():
    global num
    num += 100
    global name
    name = '张三'
    print('操作:', current_thread())


t = Thread(target=add_num)
t.start()
t.join()

print(num)
print(name)

# 2.数据安全(起因:多个线程可以同时操作同一个数据)
account = 10000


def save(num):
    print('开始存钱!')
    global account
    balance = account
    time.sleep(2)
    account = balance+num
    print(f'存钱成功!当前余额:{account}')


def draw(num):
    print('开始取钱!')
    global account
    balance = account
    if balance < num:
        print('余额不足!')
        return
    time.sleep(2)
    account = balance - num
    print(f'取钱成功!当前余额:{account}')


t1 = Thread(target=save, args=(20000,))
t2 = Thread(target=draw, args=(5000,))
t2.start()
t1.start()
t1.join()
t2.join()
print(account)
from threading import Thread, current_thread, Lock
import time

# 1.怎么加锁
"""
1)保证一个数据对应一个锁对象
锁对象 = Lock()
2)线程在第一次操作数据前加锁
锁对象.acquire()
3)线程在结束数据操作后解锁
锁对象.release()
"""
account = 10000
account_lock = Lock()


def save(num):
    print('开始存钱!')
    global account
    # 加锁
    account_lock.acquire()
    balance = account
    time.sleep(2)
    account = balance+num
    print(f'存钱成功!当前余额:{account}')
    # 解锁
    account_lock.release()


def draw(num):
    print('开始取钱!')
    global account
    # 加锁
    account_lock.acquire()
    balance = account
    if balance < num:
        print('余额不足!')
        return
    time.sleep(2)
    account = balance - num
    print(f'取钱成功!当前余额:{account}')
    # 解锁
    account_lock.release()


t1 = Thread(target=save, args=(20000,))
t2 = Thread(target=draw, args=(5000,))
t2.start()
t1.start()
t1.join()
t2.join()
print(account)
from threading import Thread, current_thread, RLock
import time

# 1.怎么加锁
"""
1)保证一个数据对应一个锁对象
锁对象 = RLock()
2)将对数据进行操作的代码放到的锁的范围内
with 锁对象:
    操作数据的代码

"""
account = 10000
account_lock = RLock()


def save(num):
    print('开始存钱!')
    with account_lock:
        global account
        balance = account
        time.sleep(2)
        account = balance+num
        print(f'存钱成功!当前余额:{account}')


def draw(num):
    print('开始取钱!')
    with account_lock:
        global account
        balance = account
        if balance < num:
            print('余额不足!')
            return
        time.sleep(2)
        account = balance - num
        print(f'取钱成功!当前余额:{account}')


t1 = Thread(target=save, args=(20000,))
t2 = Thread(target=draw, args=(5000,))
t2.start()
t1.start()
t1.join()
t2.join()
print(account)
import time
from threading import Thread
from random import randint

# 1.收集线程数据
# 定义一个全局的可变容器, 最好是队列(python中的队列本身是线程安全),将线程中产生的数据添加到容器里面
result = []


def download(name):
    print(f'{name}开始下载!')
    time.sleep(randint(2, 7))
    print(f'{name}下载结束!')
    # 返回'肖生克的救赎二进制'
    # return f'{name}的二进制'
    result.append(f'{name}的二进制')


t1 = Thread(target=download, args=('肖生克的救赎',))
t2 = Thread(target=download, args=('V字仇杀队',))
t3 = Thread(target=download, args=('这个杀手不太冷',))

re1 = t1.start()
t2.start()
t3.start()

t1.join()
t2.join()
t3.join()
print('re1:', re1)
print(result)
from queue import Queue
from threading import Thread
import time
from random import randint

# 1.什么是队列
# 1)Queue(队列)是一种容器,一般用于多线程和多进程的数据共享,因为Queue对象本身是线程安全
# 2)获取队列中的元素的时候,如果没有元素会等待,直到队列中有元素为止
# 2.操作队列
# 1)添加元素: 队列对象.put(元素)
# 2)获取元素(取一个就少一个): 队列对象.get()

# data_list = []
queue = Queue()


def add():
    for x in range(randint(50, 100)):
        # data_list.append(x)
        queue.put(x)
        print(f'添加数据{x}')
        # time.sleep(randint(1, 7))


def get():
    while True:
        # print(f'得到数据:{data_list[-1]}')
        print(f'得到数据:{queue.get()}')


t1 = Thread(target=add)
t2 = Thread(target=get)
t1.start()
# t2.start()
t1.join()
print('=======添加完成=======')
queue.put('end')

# 获取队列长度
print(queue.qsize())

while True:
    re = queue.get()
    if re == 'end':
        break
    print(re)
# for _ in range(100):
#     print(queue.get())

# print('====:', queue.get())
import threadpool
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(num):
    print('====================开始保存========================')
    while True:
        print('====保存数据的线程===', current_thread())
        result = q.get()
        print(f'=====保存{result}成功!')


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


# 2.创建线程池对象
# ThreadPool(线程的数量)
pool = threadpool.ThreadPool(10)

# 3.在线程池中添加任务
# 线程池对象.putRequest(任务对象)
for task in tasks2:
    pool.putRequest(task)
for task in tasks:
    pool.putRequest(task)

# 4.执行和等待
# 相当于先start 然后 join
pool.wait()


print('=============下载结束==============')
import threadpool
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('====================开始保存========================')
    data = []
    while True:
        result = q.get()
        if result == 'end':
            break
        data.append(result)
    print(len(data), data)


# 1.在线程池中添加下载任务
tasks = threadpool.makeRequests(download, [f'电影{x}' for x in range(100)])
pool = threadpool.ThreadPool(20)
for task in tasks:
    pool.putRequest(task)

# 2.在一个独立的线程中添加保存任务
t = Thread(target=save)
t.start()

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

print('=============下载结束==============')
from multiprocessing import Process
import time
from datetime import datetime
from threading import Thread

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


def download(name):
    # 进程中不能修改其他进程中的数据
    global a
    a += 100
    list1.append(name)

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


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

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

    # 3.等待
    p1.join()
    p2.join()
    p3.join()

    print('===============进程都结束==================')
    print(a, list1)
from multiprocessing import Pool
from datetime import datetime
import time


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


if __name__ == '__main__':
    # 1.创建进程池
    # Pool(进程数量)
    pool = Pool(3)

    # 2.添加任务(任务添加完成后会自动启动)
    # 1)一次性添加多个任务(和主进程同步执行)
    # 进程池对象.map(函数, 参数列表)
    # pool.map(download, [f'电影{x+1}' for x in range(20)])
    # 2)一次添加一个任务
    # apply()  -  添加的任务和主进程中的任务同步执行
    # apply_async()  -  添加的任务和主进程中的任务异步
    pool.apply_async(download, ('肖生克的救赎',))
    pool.apply_async(download, ('电影001',))
    pool.apply_async(download, ('电影002', ))

    # 3.关闭进程池
    # 进程池关闭后不能再往进程池中添加任务
    pool.close()
    # pool.apply(download, ('恐怖游轮',))

    for x in range(100):
        print(x)

    # 4.等待
    pool.join()
    print('===================================')
from multiprocessing import Pool
from threadpool import ThreadPool, makeRequests
import time
from threading import Thread


# 用三个进程,每个进程中有10个线程来下载200个电影


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


def create_thread(names):
    t_pool = ThreadPool(10)
    tasks = makeRequests(download, names)
    for t in tasks:
        t_pool.putRequest(t)
    t_pool.wait()


if __name__ == '__main__':
    # 创建进程池
    pool = Pool(4)

    # 创建任务
    tasks = []
    ts = []
    for x in range(1, 200 + 1):
        ts.append(x)
        if x % 50 == 0:
            tasks.append(ts)
            ts = []

    pool.map(create_thread, tasks)

    print(f'=====================结束===================')
import threadpool
from threadpool import ThreadPool
from queue import Queue
import time
from random import randint
from threading import Thread


q = Queue()


def add(q):
    print(q)
    for x in range(100):
        q.put(x)
        print(f'添加数据:{x}')
        time.sleep(randint(1, 7))


def get(q: Queue):
    while True:
        print('取到数据:', q.get())


t1 = Thread(target=add, args=(q,))
t2 = Thread(target=get, args=(q,))
t1.start()
t2.start()
# pool1 = ThreadPool(5)
# pool2 = ThreadPool(3)
#
# for re in threadpool.makeRequests(add, [q]):
#     pool1.putRequest(re)
#
#
# for re in threadpool.makeRequests(get, [q]):
#     pool2.putRequest(re)
#
# pool1.wait()
# pool2.wait()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值