5.16笔记

本文深入解析了同步和异步的概念,通过生动的例子帮助理解。并详细介绍了多线程环境下的线程同步机制,包括互斥锁的使用及优缺点,探讨了死锁现象及其预防方法。同时,讲解了生产者消费者模式和协程的基本原理。

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

#同步 异步的概念
#同步:同步就是协同步调,按预定的先后次序进行运行,如:你先说,我再说,“同”是指协同,协助,互相配合
#如进程、线程同步,可以理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某些结果,于是停下来,示意B运行,B依言而行,再将结果给A,A再继续操作

同步调用类似 你 喊 你朋友吃饭,你朋友在忙,你就在那里一直等,等你朋友忙完了你们一起去
#异步:异步调用就是 你 喊 你朋友吃饭,你朋友说知道了,待会忙完去找你,你就去做别的了

from multiprocessing import Pool
import time
import os

def download():
    print("进程池中的进程————pad=%d,ppid=%d--"%(os.getpid(),os.getppid()))
    for i in range(3):
        print("---%d---"%i)
        time.sleep(1)
    return "下载完成!"

def alterUser(args):
    print("---callback func--pid=%d"%os.getpid())
    print("---callback func--args=%s"%args)

if __name__ == '__main__':
    pool=Pool(3)
    pool.apply_async(func=download,callback=alterUser)

    print("-----start-----")
    pool.close()
    pool.join()
    print("-----end-----")

#互斥锁
#当多个线程几乎同时修改一个共享数据的时候,需要进行同步控制,线程同步能够保证多个线程安全的访问竞争资源(全局内容),最简单的同步机制就是使用互斥锁,某个线程要更改共享数据时,先将其锁定,此时资源的状态为锁定状态,其他线程就不能更改,直到该线程将资源状态改为非锁定状态,也就是释放资源,其他线程才能再次锁定资源,互斥锁保证了每一次只有一个线程进入写入操作,从而保证了多线程下数据的安全性

from threading import Thread,Lock
import time
g_num=0
def xian1():
    global g_num
    for i in range(10):
        lock.acquire(blocking=True)
        # time.sleep(0.1)
        print("1上锁")
        g_num+=1
        lock.release()
        print("1释放")
    print("1-----",g_num,"#")

def xian2():
    global g_num
    for i in range(50):
        lock.acquire(blocking=True)
        time.sleep(0.2)
        print("2上锁")
        g_num += 1
        lock.release()
        print("2释放")
    print("2-----", g_num, "#")

if __name__ == '__main__':
    lock=Lock()
    t1=Thread(target=xian1)
    t2=Thread(target=xian2)
    t1.start()    
    t1.join()
    t2.start() 
    t2.join()

#总结:
#锁的好处:确保了某段关键代码只能由一个线程从头到尾完整执行
#锁的坏处: 1、阻止了多线程的并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大下降了
#2、由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁

#死锁 :在多个线程共享资源的时候,如果两个线程分别占有一部分资源,并且同时等待对方额资源,就会造成死锁现象,如果锁之间相互嵌套,就有可能出现死锁。因此尽量不要出现锁之间的嵌套

import time
from threading import Thread,Lock

def func1():
    lockA.acquire()
    print("我得到A锁")
    time.sleep(1)
    lockB.acquire()
    print("我得到B锁")
    lockA.release()
    lockB.release()

def func2():
    lockB.acquire()
    print("func2B锁")
    time.sleep(1)
    lockA.acquire()
    print("func2A锁")
    lockB.release()
    lockA.release()

if __name__ == '__main__':
    lockA=Lock()
    lockB=Lock()
    t1=Thread(target=func1)
    t2=Thread(target=func2)
    t1.start()
    t2.start()

#生产者和消费者模式

import time
from queue import Queue
from threading import Thread
q= Queue(10)
def produce(name):
    count=1
    while True:
        q.put("%s包子%d"%(name,count))
        print("%s生产了包子%d"%(name,count))
        count+=1
        time.sleep(1)
def consumer(name):
    while True:
        print("{}消费{}".format(name,q.get()))
        time.sleep(1)
if __name__ == '__main__':
    t1=Thread(target=produce,args=("张三",))
    t1.start()
    t2=Thread(target=consumer,args=("李四",))
    t2.start()
    p1=Thread(target=produce,args=("王五",))
    p1.start()
    p2=Thread(target=produce,args=("赵柳",))
    p2.start()

threadLocal

import time
import threading
from threading import Thread

loc_s = threading.local()


def process():
    std = loc_s.name
    num = loc_s.num
    print("hello%s,学号%s,线程%s" % (std, num, threading.current_thread()))


def process_thread(name, num):
    loc_s.name = name
    loc_s.num = num
    time.sleep(1)
    process()


if __name__ == '__main__':
    t1 = Thread(target=process_thread, args=("张三", "001"), name="线程1")
    t2 = Thread(target=process_thread, args=("李四", "002"), name="线程2")
    t1.start()
    t2.start()

#全局解释器锁

import time
from threading import Thread
def jisuan():
    start=time.time()
    he=0
    for i in range(10000000):
        he+=1
    end=time.time()
    print(end-start)
if __name__ == '__main__':
    t1=Thread(target=jisuan)
    t1.start()
    t1=Thread(target=jisuan)
    t1.start()

#协程
def A():

    for i in range(2):
        print("A-----")
        yield i
def B(a):
    for i in range(2):
        print("B-----")
        next(a)
if __name__ == '__main__':
    a=A()
    B(a)  

#拓展

import gevent,time
def f1():
    for i in range(3):
        print("this is f1",i)
        gevent.sleep(1)
def f2():
    for i in range(3):
        print("this is f2",i)
        gevent.sleep(1)
if __name__ == '__main__':
    t1=gevent.spawn(f1)
    t2=gevent.spawn(f2)
    gevent.joinall([t1,t2]) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值