Python多任务(3.线程--多线程共享全局变量,利用同步解决资源竞争,利用互斥锁)

1. 线程之间是共享全局变量的

    验证代码:

import threading
import time

# 定义一个全局变量
g_num = 100

def test1():         # 修改g_num的值
    global g_num
    g_num += 1
    print("-----in test1 g_num=%d-----"%g_num)


def test2():         # 打印g_num
    print("-----in test2 g_num=%d-----"%g_num)


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

    t1.start()
    time.sleep(1)

    t2.start()
    time.sleep(1)

    print("-----in main Thread g_num = %d-----"% g_num)

if __name__ == '__main__':
    main()

    结果为:   可以看到在test1函数中利用子线程修改了值,在test2中和主函数中也会改变

            -----in test1 g_num=101-----
             -----in test2 g_num=101-----
            -----in main Thread g_num = 101-----

 2.共享全局变量的问题:----->会产生资源竞争的问题

    利用线程同步的互斥锁来解决

    (1) 同步: 同步就是协同步调,按预定的先后次序进行运行。

         “同”:  不是一起动作,而是指协同、协助、互相配合。

          如进程、线程同步,可理解为进程或线程A和B一块配合执行,A执行到一定程度时要依靠B的某个结果,于是停下                来,示意B运行,再将结果给A,A再执行

(2)互斥锁:  当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制
           互斥锁为资源引入一个状态: 锁定/非锁定

            可以这样理解:   

                  某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改,直到该线程释放 资                源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。

  (3)  创建互斥锁(threading模块中定义Lock类,可以方便的处理锁定):

            mutex = threading.Lock()        #   创建     

            mutex.acquire()                      #   锁定        (上锁)

             mutex.release()                      #  释放         (解锁)

         同一把锁只能上一次,创建后默认是没有上锁的状态,那么acquire()不会堵塞,如果已经被其他线程上了锁,那么             此 时acquire()就会堵塞,直到这个锁被解锁为止。

如下例子:

   (1)  没加锁之前,进行一个加法运算,会发现结果不对,,没加锁之前运行的结果是

-----in test1 number=1084914-----
-----in test2 number=1156328-----
-----in main number=1156328-----

   (2)加上锁之后,随便运行结果都是正确的:

-----in test1 number=1000000-----
-----in test2 number=2000000-----
-----in main number=2000000-----

   加上锁之后的代码 

import threading
import time

# 定义一个全局变量
number = 0

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

def test1(temp):
    global number
    '''上锁'''
    mutex.acquire()
    for i in range(temp):
        number += 1
    '''解锁'''
    mutex.release()
    print("-----in test1 number=%s-----" % number)

def test2(temp):
    global number
    '''上锁'''
    mutex.acquire()
    for i in range(temp):
        number += 1
    '''解锁'''
    mutex.release()
    print("-----in test2 number=%s-----" % number)

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 number=%s-----"% number)

if __name__ == '__main__':
    main()

 

你可能感兴趣的:(Python多任务,Python进阶)