线程的那点事情

Posted nerdlerss

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程的那点事情相关的知识,希望对你有一定的参考价值。

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\\n" % 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\\n" % 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

 

以上是关于线程的那点事情的主要内容,如果未能解决你的问题,请参考以下文章

苹果工程师对iOS线程开发的那点事津津乐道

synchronized 与 Lock 的那点事

数据库读写分离与事务纠缠的那点坑

关于电源的那点事

Python#规范# 关于日志的那点事

关于缓存一致性协议MESIStoreBufferInvalidateQueue内存屏障Lock指令和JMM的那点事