多线程任务的缺点——资源竞争

 1、多线程导致资源竞争,全局变量出现混乱

import threading
import time


# 定义全局变量
global_num = 0

def test1(num):
    global global_num
    for i in range(num):
        global_num += 1
    print("----in test1 global_num = %d -----" % global_num)


def test2(num):
    global global_num
    for i in range(num):
        global_num += 1
    print("----in test2 global_num = %d -----" % global_num)

def main():
    t1 = threading.Thread(target = test1,args=(1000000,))
    t2 = threading.Thread(target = test2,args=(1000000,))

    t1.start()
    t2.start()

    # 等待上面的两个线程执行完毕
    time.sleep(2)

    print("----in main global_num = %d -----" % global_num)

if __name__ == "__main__":
    main()
----in test2 global_num = 1120832 -----
----in test1 global_num = 1143178 -----
----in main global_num = 1143178 -----

2、加锁

加锁方式1

import threading
import time


# 定义全局变量
global_num = 0

def test1(num):
    global global_num
    mutex.acquire()
    for i in range(num):
        global_num += 1
    mutex.release()
    print("----in test1 global_num = %d -----" % global_num)

def test2(num):
    global global_num
    mutex.acquire()
    for i in range(num):
        global_num += 1
    mutex.release()
    print("----in test2 global_num = %d -----" % global_num)

mutex = threading.Lock() # 创建一个互赤锁,默认是没有上锁的

def main():
    t1 = threading.Thread(target = test1,args=(1000000,))
    t2 = threading.Thread(target = test2,args=(1000000,))

    t1.start()
    t2.start()

    # 等待上面的两个线程执行完毕
    time.sleep(2)

    print("----in main global_num = %d -----" % global_num)

if __name__ == "__main__":
    main()
----in test1 global_num = 1000000 -----
----in test2 global_num = 2000000 -----
----in main global_num = 2000000 -----

加锁方式2 

import threading
import time


# 定义全局变量
global_num = 0

def test1(num):
    global global_num
    for i in range(num):
        mutex.acquire()
        global_num += 1
        mutex.release()
    print("----in test1 global_num = %d -----" % global_num)

def test2(num):
    global global_num
    for i in range(num):
        mutex.acquire()
        global_num += 1
        mutex.release()
    print("----in test2 global_num = %d -----" % global_num)

mutex = threading.Lock() # 创建一个互赤锁,默认是没有上锁的

def main():
    t1 = threading.Thread(target = test1,args=(1000000,))
    t2 = threading.Thread(target = test2,args=(1000000,))

    t1.start()
    t2.start()

    # 等待上面的两个线程执行完毕
    time.sleep(2)

    print("----in main global_num = %d -----" % global_num)

if __name__ == "__main__":
    main()
----in test1 global_num = 1954922 -----
----in test2 global_num = 2000000 -----
----in main global_num = 2000000 -----

3、死锁的产生 

import threading
import time

class MyThread1(threading.Thread):
    def run(self):
        # 对mutexA上锁
        mutexA.acquire()
        print("...")
        time.sleep(1)

        mutexB.acquire() # 注意执行到这里,需要对上B锁,而B锁已经被另外一个线程获取了,需要等待其释放,无法往下执行,则A锁无法释放
        print("...")
        mutexB.release()

        mutexA.release()


class MyThread2(threading.Thread):
    def run(self):
        # 对mutexA上锁
        mutexB.acquire()
        print("...")
        time.sleep(1)

        mutexA.acquire()# 注意执行到这里,要上A锁,而A锁被另外一个线程上了锁,无法释放,导致死锁
        print("...")
        mutexA.release()

        mutexB.release()

def main():
    t1 = MyThread1()
    t2 = MyThread2()
    t1.start()
    t2.start()

mutexA = threading.Lock()
mutexB = threading.Lock()

if __name__=="__main__":
    main()

 

 

你可能感兴趣的:(多线程任务的缺点——资源竞争)