• python 线程


    线程锁(互斥锁Mutex)

    一个进程下可以启动多个线程,多个线程共享父进程的内存空间,也就意味着每个线程可以访问同一份数据,此时,如果2个线程同时要修改同一份数据,这样就可能使结果不正确,每次运行的结果不同,为了避免自己在还没改完的时候别人也来修改此数据,可以给这个数据加一把锁, 这样其它线程想修改此数据时就必须等待你修改完毕并把锁释放掉后才能再访问此数据,这里的锁称为线程锁。

    在python2.几的版本上会有多线程同时修改同一数据,结果不同的情况,在python3上不会出现这种情况。

    没加锁的效果:加大线程多试几遍 。

    #conding:UTF-8
    import threading,time  
    num=0
    def run(m):  #子线程
        global num
        print'take',m
        time.sleep(2) #方法中的时间间隔在显示结果时间上不显现,因为t1.start()是并发执行的。
        print'run结束',m
        num+=1 #多线程同时操作
    
    app=[]
    start_time=time.time()
    for i in range(10):  #主线程
        t1=threading.Thread(target=run,args=('t-%s'%i,))  
        
        t1.start()   #循环中的对象并发执行调用run函数。把time.sleep(2)放到t1.start()的上面时间间隔就会显现。
        app.append(t1)
    for t in app:
        t.join()  #等待线程结束  
     
    print 'cost:',time.time()-start_time
    print num   #得出num的值
    

    python2添加锁,加锁后线程就会形成串行。

    #conding:UTF-8
    import threading,time  
    num=0
    def run(m):  #子线程
        sock.acquire() #解锁
        global num
        print'take',m
        time.sleep(2) #方法中的时间间隔在显示结果时间上不显现,因为t1.start()是并发执行的。
        print'run结束',m
        num+=1
        sock.release()#释放锁
    sock=threading.Lock()
    app=[]
    start_time=time.time()
    for i in range(10):  #主线程
        t1=threading.Thread(target=run,args=('t-%s'%i,))     
        t1.start()   #循环中的对象并发执行调用run函数。把time.sleep(2)放到t1.start()的上面时间间隔就会显现。
        app.append(t1)
    for t in app:
         t.join()  #等待线程结束   
    print 'cost:',time.time()-start_time
    print num   
        
    

    结果形成串行:

    take t-0
    run结束 t-0
    take t-1
    run结束 t-1
    take t-2
    run结�� t-2
    take t-3
    run结束 t-3
    take t-4
    run结�� t-4
    take t-5
    run结�� t-5
    take t-6
    run结束 t-6
    take t-7
    run结�� t-7
    take t-8
    run结�� t-8
    take t-9
    run结束 t-9
    cost: 20.007999897
    10

    递归锁(互斥锁)

    在一个大锁中还要再包含子锁 

    #conding:UTF-8
    import threading,time
     
    def run1():
        print("grab the first part data")
        lock.acquire()
        global num
        num +=1
        lock.release()
        return num
    def run2():
        print("grab the second part data")
        lock.acquire()
        global  num2
        num2+=1
        lock.release()
        return num2
    def run3():
        
        lock.acquire()
        res = run1()
        print('--------between run1 and run2-----')
        res2 = run2()
        lock.release()
        print(res,res2) 
    if __name__ == '__main__':
     
        num,num2 = 0,0
        lock = threading.RLock() #递归锁  这里如果不带R的话,将会出现找不到锁,死循环的情况。
        for i in range(10):
            t = threading.Thread(target=run3)
            t.start()
    while threading.active_count() != 1:
        print(threading.active_count())
        print(num,num2)
    else:
        print('----all threads done---')
        print(num,num2)
    

    信号量

    互斥锁 同时只允许一个线程更改数据,而信号量是同时允许一定数量的线程更改数据。

    #conding:UTF-8
    import threading,time 
    def run(n):
        semaphore.acquire() #信号获取
        time.sleep(2)
        print("run the thread: %s
    " %n)
        semaphore.release()  #信号释放
    if __name__ == '__main__': 
        semaphore  = threading.BoundedSemaphore(5) #定义信号量对象,最多允许5个线程同时运行
        for i in range(20):
            t = threading.Thread(target=run,args=(i,))
            t.start() 
    while threading.active_count() != 1:
        pass #print threading.active_count()
    else:
        print('----all threads done---')
    

     Events(事件)

    通过Event来实现两个或多个线程间的交互。

    event=threading.Event()   #定义事件对象

    event.wait()  # Event对象wait的方法只有在内部信号为真的时候才会很快的执行并完成返回。当Event对象的内部信号标志位假时,则wait方法一直等待到其为真时才返回。

    event.set() #  使用Event的set()方法可以设置Event对象内部的信号标志为真。Event对象提供了isSet()方法来判断其内部信号标志的状态,当使用event对象的set()方法后,isSet()方法返回真.

    event.clear() # 使用Event对象的clear()方法可以清除Event对象内部的信号标志,即将其设为假,当使用Event的clear方法后,isSet()方法返回假

    以下游戏规则:

    红绿灯的例子,即起动一个线程做交通指挥灯,生成几个线程做车辆,车辆行驶按红灯停,绿灯行的规则。

    #conding:UTF-8
    import time
    import threading
    count=0
    event=threading.Event() #创建Event对象
    event.set() #设置标志位
    def lingter():
        global count
        while True:
            if count<5:#5秒内绿灯亮
                print 'greed lignt is on....'
            elif count>=5and count<10:#之外红灯亮        
                event.clear() #清空标志位
                print 'red lignt is wait....'
            else:
                count=0
                event.set()               
            count+=1        
            time.sleep(1)
    def car(name):
        while True:
            if event.is_set():  #判断标志状态          
                print '%s is running...'%name            
            else:
                print '%s is waitting...'%name   
                event.wait()
                print '%s is going run...'%name
            time.sleep(1)
    lingt=threading.Thread(target=lingter,)
    lingt.start()
    car1=threading.Thread(target=car,args=('car1',))
    car1.start()
    
  • 相关阅读:
    一句SQL实现MYSQL的递归查询
    人生不过一个字【Life is but a word】
    VS2008 如何将Release版本设置可以调试的DEBUG版本
    微软 2018 年第一笔收购:文件存储公司 Avere Systems
    设置系统时间
    OpenVZ安装指南,一种操作系统级别的虚拟化技术
    云平台DevOps实践
    路由(Routing)
    Ubuntu命令
    net mvc中angular
  • 原文地址:https://www.cnblogs.com/iexperience/p/9306842.html
Copyright © 2020-2023  润新知