线程安全问题

 - 先来看一段代码

import time

class Foo(object):
    pass

foo = Foo()

def add(i):
    foo.num = i
    time.sleep(1)
    print(foo.num)

for i in range(20):
    add(i)

 - 结果是每一秒输出一个,假如一个网站同时有20个用户来进行访问,每一个人加载代码需要一秒,那么对后访问的人体验非常差,这个时候我们就需要开启线程

 - 代码改进

import time
import  threading

class Foo(object):
    pass

foo = Foo()

def add(i):
    foo.num = i
    time.sleep(1)
    print(foo.num,i)

for i in range(20):
    threading.Thread(target=add,args=(i,)).start()

 - 此时的结果为,这样还是行不通

19 0
19 1
19 4
19 5
19 2
19 3
19 8
19 9
19 6
19 7
19 12
19 14
19 15
19 11
19 10
19 13
19 17
19 18
19 16
19 19
View Code

 - 解决方法

import time
import  threading
from threading import local 
class Foo(local):
    pass

foo = Foo()

def add(i):
    foo.num = i
    time.sleep(1)
    print(foo.num,i)

for i in range(20):
    threading.Thread(target=add,args=(i,)).start()

 - 结果

0 0
2 2
3 3
1 1
5 5
6 6
4 4
8 8
7 7
9 9
12 12
10 10
11 11
14 14
16 16
15 15
13 13
19 19
17 17
18 18
View Code

 - 为什么继承了local 就成功了呢?

 - 首先要知道

threading.current_thread().ident # 线程id

 - local本质其实是通过唯一的线程ID来进行取值的

 - 来看一段伪代码

"""
{
    1616 : foo.num = 0, 
    13128 : foo.num = 1,
    13540 : foo.num = 2,
}
"""

 - local 会拿出这么一块空间来存储对应关系,从而达到最快效率的运算,其实就是用空间来换取时间

节省时间 ----> 开线程 -----> 线程安全 -----> 占用空间

 

posted @ 2019-01-09 17:07  阵浊秀  阅读(84)  评论(0编辑  收藏  举报