线程同步问题

  • 临界资源

      多一个线程同时运行,有时线程之间需要共享数据,一个线程需要其他线程的数据,否则就不能保证程序运行结果的正确性。 

    多个线程间共享的数据称为共享资源或临界资源,由于是CPU负责线程的调度,程序员无法精确控制多线程的交替顺序。这种情况下,多线程对临界资源的访问有时会导致数据的不一致性。

  • 多线程同步

   可以为这些资源对象加上一把“互斥锁”,在任一时刻只能由一个线程访问,即使该线程出现阻塞,该对象的被锁定状态也不会解除,其他线程仍不能访问该对象,这就是多线程同步。线程同步保证线程安全的重要手段,但是线程同步客观上会导致性能下降。
 
    对于简单线程同步可以使用threading模块的Lock类,Lock对象有两中状态:“锁定”和“未锁定”,默认是“未锁定”状态,Lock对象有两个方法acquire()和release()实现锁定和解锁,acquire()方法可以实现锁定,使得Lock对象进入“锁定”;release()方法可以实现解锁,使得Lock对象进入“未锁定”。

下图的例子为模拟两个购票网点的购票情况:

import threading
import time
class TicketDB:
    def __init__(self):
        self.ticket_count=5

    def get_ticket_count(self):
        return self.ticket_count
    def sell_ticket(self):
        #线程休眠等待用户付款
        time.sleep(1)
        print('当前线程为{0}'.format(threading.current_thread().name))
        print('第{0}号票已经售出'.format((self.ticket_count)))
        self.ticket_count-=1

db=TicketDB()
lock=threading.Lock()
def thread1_body():
    global db
    global lock
    while True:
        lock.acquire()
        curr_ticket_count=db.get_ticket_count()
        if curr_ticket_count>0:
            db.sell_ticket()
        else:
            lock.release()
            break
        lock.release()
        time.sleep(1)
def thread2_body():
    global db
    global lock
    while True:
        lock.acquire()
        curr_ticket_count = db.get_ticket_count()
        if curr_ticket_count > 0:
            db.sell_ticket()
        else:
            lock.release()
            break
        lock.release()
        time.sleep(1)
def main():
    t1=threading.Thread(target=thread1_body)
    t1.start()
    t2=threading.Thread(target=thread2_body)
    t2.start()
if __name__ == '__main__':
    main()


 

 

 

你可能感兴趣的:(Python)