• Python 线程复习


    修改全局变量,设立flag来避免线程间数据冲突,低效率版

    from threading import Thread
    import time
    
    g_num=0
    g_flag = 1
    
    def test1():
        global g_num
        global g_flag
        if g_flag ==1:
            for i in range(1000000):
                g_num += 1 
                
            g_flag = 0
        print('----test1----g_num=%d'%g_num)
    
    
    def test2():
        global g_num
        global g_flag
        while True:
            if g_flag != 1:
                for i in range(1000000):
                    g_num += 1
                break
                
        print('----test2----g_num=%d' % g_num)
    p1 = Thread(target=test1)
    p1.start()
    
    p2 = Thread(target=test2)
    p2.start()

    修改全局变量,互斥锁(高效版),否则不用枷锁

    from threading import Thread,Lock
    import time
    
    g_num=0
    
    def test1():
        global g_num
        for i in range(1000000):
            mutex.acquire()  # 上锁
            g_num += 1
            mutex.release() #解锁
        print('----test1----g_num=%d'%g_num)
    
    def test2():
        global g_num
        for i in range(1000000):
            mutex.acquire()  # 上锁
            g_num += 1
            mutex.release()  # 解锁
    
        print('----test2----g_num=%d' % g_num)
    
    mutex = Lock()
    
    p1 = Thread(target=test1)
    p1.start()
    
    p2 = Thread(target=test2)
    p2.start()

    死锁

    添加超时时间 mutex.acquire(timeout = 1)

    银行家算法-先满足最小需求单位,等待

     ThreadLocal

    可以解决线程间全局变量,不会因为线程修改全局变量而修改,完成数据间传递,不会因为程序一样而导致数据错乱

    代码如下:

    import threading
    
    # 创建全局变量threadLocal
    loacl_school = threading.local()
    
    def process_student():
        # 获取当前线程关联的student
        std = loacl_school.student
        print(std)
    
    def process_thrad(name):
        # 绑定threadlocal的student
        loacl_school.student = name
        process_student()
    
    t1 = threading.Thread(target=process_thrad,args=('laowang',),name='thread-a')
    t2 = threading.Thread(target=process_thrad,args=('xiaowang',),name='thread-b')
    
    t1.start()
    t2.start()
    
    t1.join()
    t2.join()

     异步

    callback=func,并把之前函数返回值复制到func

    GIL 全局解释器锁

    解决办法:1、用多进程2、用C语言写关键部分

    python部分

    from ctypes import *
    from threading import Thread
    
    # 加载动态库
    lib = cdll.LoadLibrary('./libdeadloop.so')
    
    #创建一个子线程,让其执行C语言编写的函数,此函数是一个死循环
    t = Thread(target=lib.DeadLoop)
    t.start()
    
    # 主线程页调用C语言写的那个死循环函数
    lib.DeadLoop()
    
    while True:
        pass

    C语言代码

    {
        while(1){
            ;
        }
    
    }

    生成libdealloop.so库

    线程同步

    import threading
    
    mylock = threading.RLock()
    num = 0
    
    class myThread(threading.Thread):
        def __init__(self,name):
            threading.Thread.__init__(self,name=name)
    
        def run(self):
            global num
            while True:
                mylock.acquire()
                print('%s locked,Number:%d'% (threading.current_thread().name,num))
                if num>=4:
                    mylock.release()
                    print('%s locked,Number:%d'% (threading.current_thread().name,num))
                    break
                num+=1
                print('%s locked,Number:%d'% (threading.current_thread().name,num))
                mylock.release()
    
    if __name__ =='__main__':
        thread1 = myThread('Thread_1')
        thread2 = myThread('Thread_2')
        thread1.start()
        thread2.start()

  • 相关阅读:
    C#日期与时间
    使用IIS部署WebDAV
    永久有效,最新IntelliJ IDEA 2021.1.1激活破解教程,亲测有效
    LNC(宝元)机床的IP设置和数据采集
    KND(凯恩帝)机床的IP设置
    国密算法SM1-SM4简介
    WPF中根据数据展示不同UI控件的做法
    WPF中ListView滚动到当前行的几种方法
    WPF中对于异步返回的绑定
    .net类库名称空间冲突怎么办?
  • 原文地址:https://www.cnblogs.com/Erick-L/p/7137627.html
Copyright © 2020-2023  润新知