一个线程写,另一个线程读,需要加锁吗

 我来答
fallx
2018-02-02 · TA获得超过5485个赞
知道大有可为答主
回答量:2321
采纳率:73%
帮助的人:718万
展开全部
  1. 多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了。

  2. 来看看多个线程同时操作一个变量怎么把内容给改乱了:

  3. import time, threading# 假定这是你的银行存款:balance = 0def change_it(n):
        # 先存后取,结果应该为0:
        global balance
        balance = balance + n
        balance = balance - ndef run_thread(n):
        for i in range(100000):#当这个数足够大时,结果总会出现问题的
            change_it(n)

    t1 = threading.Thread(target=run_thread, args=(5,))
    t2 = threading.Thread(target=run_thread, args=(8,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print(balance)
  4. balance = balance + n

  5. 我们定义了一个共享变量balance,初始值为0,并且启动两个线程,先存后取,理论上结果应该为0,但是,由于线程的调度是由操作系统决定的,当t1、t2交替执行时,只要循环次数足够多,balance的结果就不一定是0了。

    原因是因为高级语言的一条语句在CPU执行时是若干条语句,即使一个简单的计算:

    也分两步:

    计算balance + n,存入临时变量中;

    将临时变量的值赋给balance。

  6. 也就是可以看成:

    x = balance + nbalance = x


    由于x是局部变量,两个线程各自都有自己的x,当代码正常执行时:

    初始值 balance = 0

    t1: x1 = balance + 5 # x1 = 0 + 5 = 5

    t1: balance = x1     # balance = 5

    t1: x1 = balance - 5 # x1 = 5 - 5 = 0

    t1: balance = x1     # balance = 0

    t2: x2 = balance + 8 # x2 = 0 + 8 = 8

    t2: balance = x2     # balance = 8

    t2: x2 = balance - 8 # x2 = 8 - 8 = 0

    t2: balance = x2     # balance = 0

    结果 balance = 0

    是t1和t2是交替运行的,如果操作系统以下面的顺序执行t1、t2:

    初始值

    balance = 0

    t1: x1 = balance + 5  # x1 = 0 + 5 = 5

    t2: x2 = balance + 8  # x2 = 0 + 8 = 8

    t2: balance = x2      # balance = 8

    t1: balance = x1      # balance = 5

    t1: x1 = balance - 5  # x1 = 5 - 5 = 0

    t1: balance = x1      # balance = 0

    t2: x2 = balance - 8  # x2 = 0 - 8 = -8

    t2: balance = x2   # balance = -8

    结果 balance = -8

    究其原因,是因为修改balance需要多条语句,而执行这几条语句时,线程可能中断,从而导致多个线程把同一个对象的内容改乱了。

    两个线程同时一存一取,就可能导致余额不对,你肯定不希望你的银行存款莫名其妙地变成了负数,所以,我们必须确保一个线程在修改balance的时候,别的线程一定不能改。

    如果我们要确保balance计算正确,就要给change_it()上一把锁,当某个线程开始执行change_it()时,我们说,该线程因为获得了锁,因此其他线程不能同时执行change_it(),只能等待,直到锁被释放后,获得该锁以后才能改。由于锁只有一个,无论多少线程,同一时刻最多只有一个线程持有该锁,所以,不会造成修改的冲突。

    from :网页链接

    借的廖雪峰的python3教程来说事.

duyi324
2018-02-02 · TA获得超过292个赞
知道小有建树答主
回答量:322
采纳率:70%
帮助的人:175万
展开全部
说法不一,如果不加锁的话不知道读到的数据是写之前还是写之后,感觉为了防止意外,还是加个读写锁比较好。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式