2017-6-12

作者: kevinyings | 来源:发表于2017-06-13 08:47 被阅读0次

    <div id="table-of-contents">
    <h2>Table of Contents</h2>
    <div id="text-table-of-contents">
    <ul>
    <li><a href="#org17ead76">1. 线程</a></li>
    <li><a href="#org94bfd89">2. thread safety</a></li>
    <li><a href="#org5f292e0">3. 同步</a></li>
    <li><a href="#org3ab5a87">4. 锁的使用</a></li>
    <li><a href="#org7feeb49">5. 死锁</a></li>
    <li><a href="#orgbd5f680">6. 银行家算法</a></li>
    <li><a href="#org8ab407a">7. 多线程有序的进行</a></li>
    <li><a href="#org15b1bd9">8. python 的 QUEUE</a></li>
    <li><a href="#org323f3ed">9. ThreadLocal 的使用</a></li>
    <li><a href="#org6c79613">10. multiprocess 的 callback</a></li>
    </ul>
    </div>
    </div>

    <a id="org17ead76"></a>

    线程

    1.每个线程一定会有一个名字,尽管上面的例子中没有指定线程对象的 name,但是 python 会自动为线程指定一个名字。
    2.当线程的 run()方法结束时该线程完成。
    3.无法控制线程调度程序,但可以通过别的方式来影响线程调度的方式。
    4.线程的几种状态

    <a id="org94bfd89"></a>

    thread safety

    在一个进程内的所有线程共享全局变量,能够在不适用其他方式的前提下完成多线程之间的数据共享(这点要比多进程要好)
    缺点就是,线程是对全局变量随意遂改可能造成多线程之间对全局变量的混乱(即线程非安全)

    <a id="org5f292e0"></a>

    同步

    from threading import Thread
    import time
    g_num = 0
    def test1():
        global g_num
        for i in range(1000000):
            g_num += 1
        print("---test1---g_num=%d"%g_num)
    def test2():
        global g_num
        for i in range(1000000):
            g_num += 1
    
        print("---test2---g_num=%d"%g_num)
    
    p1 = Thread(target=test1)
    p1.start()
    #time.sleep(3) #取消屏蔽之后 再次运行程序,结果会不一样,,,为啥呢?
    p2 = Thread(target=test2)
    p2.start()
    print("---g_num=%d---"%g_num) 
    

    —gnum=463123—
    —test1—gnum=1435664
    —test2—gnum=1725941

    gnum+=1 是线程不安全的 gnum=gnum+1

    <a id="org3ab5a87"></a>

    锁的使用

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

    <a id="org7feeb49"></a>

    死锁

    在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。

    import threading
    import time
    
    class MyThread1(threading.Thread):
        def run(self):
            if mutexA.acquire():
                print(self.name+'----do1---up----')
                time.sleep(1)
    
                if mutexB.acquire():
                    print(self.name+'----do1---down----')
                    mutexB.release()
                mutexA.release()
    
    class MyThread2(threading.Thread):
        def run(self):
            if mutexB.acquire():
                print(self.name+'----do2---up----')
                time.sleep(1)
                if mutexA.acquire():
                    print(self.name+'----do2---down----')
                    mutexA.release()
                mutexB.release()
    
    mutexA = threading.Lock()
    mutexB = threading.Lock()
    
    if __name__ == '__main__':
        t1 = MyThread1()
        t2 = MyThread2()
        t1.start()
        t2.start()
    

    <a id="orgbd5f680"></a>

    银行家算法

    <a id="org8ab407a"></a>

    多线程有序的进行

     from threading import Thread, Lock
    from time import sleep
    '''
        等待锁的打开:阻塞-唤醒  机制
    
        还有一种实现形式:轮循,效率低
    '''
    
    class Task1(Thread):
        def run(self):
            while True:
                sleep(3)
                print("Task 1")
                if lock1.acquire():
                    print("------Task 1 -----")
                    sleep(0.5)
                    lock2.release()
    
    class Task2(Thread):
        def run(self):
            while True:
                sleep(6)
                print("Task 2")
                if lock2.acquire():
                    print("------Task 2 -----")
                    sleep(0.5)
                    lock3.release()
    
    class Task3(Thread):
        def run(self):
            while True:
                sleep(4)
                print("Task 3")
                if lock3.acquire():
                    print("------Task 3 -----")
                    sleep(0.5)
                    lock1.release()
    
    # 使用 Lock 创建出的锁默认没有“锁上”
    lock1 = Lock()
    # 创建另外一把锁,并且“锁上”
    lock2 = Lock()
    lock2.acquire()
    # 创建另外一把锁,并且“锁上”
    lock3 = Lock()
    lock3.acquire()
    
    if __name__ == '__main__':
        t1 = Task1()
        t2 = Task2()
        t3 = Task3()
    
        t1.start()
        t2.start()
        t3.start() 
    

    <a id="org15b1bd9"></a>

    python 的 QUEUE

    Python 的 Queue 模块中提供了同步的、线程安全的队列类,包括 FIFO(先入先出)队列 Queue,LIFO(后入先出)队列 LifoQueue,和优先级队列 PriorityQueue。这些队列都实现了锁原语(可以理解为原子操作,即要么不做,要么就做完),能够在多线程中直接使用。可以使用队列来实现线程间的同步。
    对于 Queue,在多线程通信之间扮演重要的角色
    添加数据到队列中,使用 put()方法
    从队列中取数据,使用 get()方法
    判断队列中是否还有数据,使用 qsize()方法

    import threading
    import time
    from queue import Queue
    
    class Producer(threading.Thread):
        def run(self):
            global queue
            count = 0
            while True:
                if queue.qsize() < 1000:
                    for i in range(100):
                        count = count +1
                        msg = '生成产品'+str(count)
                        queue.put(msg)
                        print(msg)
                time.sleep(0.5)
    
    class Consumer(threading.Thread):
        def run(self):
            global queue
            while True:
                if queue.qsize() > 100:
                    for i in range(3):
                        msg = self.name + '消费了 '+queue.get()
                        print(msg)
                time.sleep(1)
    
    if __name__ == '__main__':
        queue = Queue()
        for i in range(500):
            queue.put('初始产品'+str(i))
        for i in range(2):
            p = Producer()
            p.start()
        for i in range(5):
            c = Consumer()
            c.start()
    

    生成产品 1 生成产品 1
    生成产品 2

    生成产品 2
    生成产品 3 生成产品 3Thread-20 消费了 初始产品 0

    Thread-20 消费了 初始产品 2
    Thread-21 消费了 初始产品 1

    生成产品 4Thread-22 消费了 初始产品 4Thread-20 消费了 初始产品 5
    生成产品 4 生成产品 5

    生成产品 5 生成产品 6
    生成产品 7

    <a id="org323f3ed"></a>

    ThreadLocal 的使用

    联系同一进程的不同片段

    import threading
    local_school = threading.local()
    def process_student():
        std = local_school.student
        print('Hello, %s (in %s)' % (std, threading.current_thread().name))
    def process_thread(name):
        local_school.student = name
        process_student()
    t1 = threading.Thread(target= process_thread, args=('yongGe',), name='Thread-A')
    t2 = threading.Thread(target= process_thread, args=('老王',), name='Thread-B')
    t1.start()
    t2.start()
    t1.join()
    t2.join() 
    

    <a id="org6c79613"></a>

    multiprocess 的 callback

    相关文章

      网友评论

          本文标题:2017-6-12

          本文链接:https://www.haomeiwen.com/subject/smzrqxtx.html