zoukankan      html  css  js  c++  java
  • 线程的那点事情

    1.线程安全

    首先我们知道线程是共享资源的,在这个基础上我们提出一个问题,如果我们有一个变量a = 0

    然后10个线程都是给它+1的 然后我们执行这个10个线程,最后a = 10吗?

    我们先看下面的代码

     1 __author__ = 'Rico'
     2 #_*_coding:utf-8_*_
     3 from threading import Thread
     4 a = 0
     5 class Plusone(Thread):
     6     def __init__(self):
     7         super(Plusone,self).__init__()
     8     def run(self):
     9         global  a
    10         a += 1
    11 
    12 for i in range(30):
    13     temp =  Plusone()
    14     temp.start()
    15 
    16 print a

    如果没错的的应该输入的是30 

    但是---》

    结果是29

    当然这不是每次都会出现的,是不固定的,看电脑的配置的,和线程的个数

    由此 我们知道 变量之所以没有得到我们想要的值,是因为线程之间抢占了变量,导致了问题的发生 --->结论:Python不是一个线程安全的语言

    那么我们要自己保证线程安全了那么引出了下面的概念

    2线程锁

    我们去买衣服的时候,试衣间里面会不会出现两个人?并不会。为什么呢? 因为每个人进去之后会反锁门,走的时候才打开。这就是线程锁的概念

    我们修改下run函数

    1 def run(self):
    2         lock.acquire()
    3         global  a
    4         a += 1
    5         print a
    6         lock.release()
    lock.acquire()#在执行这个时候,线程会独占cpu
    lock.release()#释放
    在执行两个操作的时候之间其实就是单线程了


    Python有一个叫全局解释器锁的东西我们大家都知道--进行cpu操作的时候,因为全局解释器锁的原因
    你起了一个多线程,其实还是一个单线程,其他的线程其实都在切片
     1 __author__ = 'Rico'
     2 #_*_coding:utf-8_*_
     3 from threading import Thread,Lock
     4 import  time
     5 a = 0
     6 class Plusone(Thread):
     7     def __init__(self,name):
     8         self.__name = name
     9         super(Plusone,self).__init__()
    10     def run(self):
    11         global  a
    12         lock.acquire()
    13         a += 1
    14         lock.release()
    15         print "%s
    " % a
    16 lock =Lock()
    17 
    18 for i in range(200):
    19     temp =  Plusone(i)
    20     temp.start()
    21 
    22 print a

    我们在跑这个代码的时候,就可以感受到了 无论你开多少线程 最后还是顺序的切片 但是如果你把run函数变成这样

    def run(self):
            global  a
            lock.acquire()
            a += 1
            lock.release()
            time.sleep(1)
            print "%s
    " % a
    

    cpu默认都之拿来100条指令 当加入了sleep(1) 就不等了 直接切了 

    3信号量 同时允许及格线程访问同一个数据

     1 __author__ = 'Rico'
     2 #_*_coding:utf-8_*_
     3 from threading import Thread,Lock,BoundedSemaphore
     4 import  time
     5 a = 0
     6 class Plusone(Thread):
     7     def __init__(self,name):
     8         self.__name = name
     9         super(Plusone,self).__init__()
    10     def run(self):
    11         time.sleep(1)
    12         global  a
    13         samp.acquire()
    14         a += 1
    15         print "%s" % a
    16         samp.release()
    17 samp = BoundedSemaphore(10)
    18 for i in range(200):
    19     temp =  Plusone(i)
    20     temp.start()
    21 
    22 print a
  • 相关阅读:
    Java实现 LeetCode 50 Pow(x,n)
    Java实现 LeetCode 50 Pow(x,n)
    Java实现 LeetCode 49 字母异位词分组
    Java实现 LeetCode 49 字母异位词分组
    Java实现 LeetCode 49 字母异位词分组
    Java实现 LeetCode 48 旋转图像
    Java实现 LeetCode 48 旋转图像
    Java实现 LeetCode 48 旋转图像
    Java实现 LeetCode 47 全排列 II(二)
    Java实现 LeetCode 47 全排列 II(二)
  • 原文地址:https://www.cnblogs.com/nerdlerss/p/5838517.html
Copyright © 2011-2022 走看看