线程中的锁

Zss 发表于:

1.在线程1执行100万次加法的时候,线程2也会执行,而在线程1还没执行完时,并没有对g_flag进行修改,

导致线程2只判断了一次,条件并不满足,所以直接结束了,所以加上一个while 1:无限的循环来判断是否满足,

当满足的时候线程2执行一百万次的加法,但是这样子有一个缺点,虽然也可以完成任务,但是在这段时间中,

线程2一直是长时间的判断不满足,需要占用cpu的资源导致效率不高,这种方式叫做轮询,所有需要了线程的互斥锁

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
    #轮询
    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()

print("---g_num=%d---"%g_num)

2.互斥锁当条件不满足的时候,等着条件满足,是阻塞的状态,threading中定义了一个类为Lock,共享资源不出现问题

mutex = Lock() 创建一把互斥锁,默认是不上锁

mutex.acquire()上锁

mutex.release()解锁

from threading import Thread, Lock
import time

g_num = 0

def test1():
    global g_num
    #这个线程和test2线程都在抢着 对这个锁 进行上锁,如果有1方成功的上锁,那么导致另外
    #一方会堵塞(一直等待)到这个锁被解开为止
    mutex.acquire()
    for i in range(1000000):
        g_num += 1
    mutex.release()#用来对mutex指向的这个锁 进行解锁,,,只要开了锁,那么接下来会让所有因为
                    #这个锁 被上了锁 而堵塞的线程 进行抢着上锁

    print("---test1---g_num=%d"%g_num)

def test2():
    global g_num
    mutex.acquire()
    for i in range(1000000):
        g_num += 1
    mutex.release()

    print("---test2---g_num=%d"%g_num)

#创建一把互斥锁,这个锁默认是没有上锁的
mutex = Lock()

p1 = Thread(target=test1)
p1.start()

#time.sleep(3) #取消屏蔽之后 再次运行程序,结果会不一样,,,为啥呢?

p2 = Thread(target=test2)
p2.start()

print("---g_num=%d---"%g_num)

3.多线程对同一个资源竞争使用的时候需要加锁,所以加锁的原则是在保证功能的运行下加锁的代码越少越好,以上上锁解锁可以放在for循环中