线程数据不安全现象

Posted wyh0717

tags:

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

线程数据不安全现象

from threading import Thread
n = 0
def add():
    for i in range(500000):
        global n
        n += 1
def sub():
    for i in range(500000):
        global n
        n -= 1

t_l = []
for i in range(2):
    t1 = Thread(target=add)
    t1.start()
    t2 = Thread(target=sub)
    t2.start()
    t_l.append(t1)
    t_l.append(t2)
for t in t_l:
    t.join()
print(n)
#结果n不为0
from threading import Thread
import time
n = []
def append():
    for i in range(500000):
        n.append(1)
def pop():
    for i in range(500000):
        if not n:
            time.sleep(0.0000001)
        n.pop()

t_l = []
for i in range(20):
    t1 = Thread(target=append)
    t1.start()
    t2 = Thread(target=pop)
    t2.start()
    t_l.append(t1)
    t_l.append(t2)
for t in t_l:
    t.join()
print(n)
#使用append pop方法数据安全
+= -=  *= /= while if 数据不安全   + 和 赋值是分开的两个操作
append pop strip数据安全 列表中的方法或者字典中的方法去操作全局变量的时候 数据安全的
线程之间也存在数据不安全

线程锁

from threading import Thread,Lock
n = 0
def add(lock):
    for i in range(500000):
        global n
        with lock:
            n += 1
def sub(lock):
    for i in range(500000):
        global n
        with lock:
            n -= 1

t_l = []
lock = Lock()
for i in range(2):
    t1 = Thread(target=add,args=(lock,))
    t1.start()
    t2 = Thread(target=sub,args=(lock,))
    t2.start()
    t_l.append(t1)
    t_l.append(t2)
for t in t_l:
    t.join()
print(n)
from threading import Thread,Lock
import time
n = []
def append():
    for i in range(500000):
        n.append(1)
def pop(lock):
    for i in range(500000):
        with lock:
            if not n:
                time.sleep(0.0000001)    # 强制CPU轮转
            n.pop()

t_l = []
lock = Lock()
for i in range(20):
    t1 = Thread(target=append)
    t1.start()
    t2 = Thread(target=pop,args=(lock,))
    t2.start()
    t_l.append(t1)
    t_l.append(t2)
for t in t_l:
    t.join()
print(n)
不要操作全局变量,不要在类里操作静态变量
+= -= *= /= if while 数据不安全
queue logging 数据安全的

单例模式

import time
class A:
    from threading import Lock
    __instance = None
    lock = Lock()
    def __new__(cls, *args, **kwargs):
        with cls.lock:
            if not cls.__instance:
                time.sleep(0.000001)   # cpu轮转
                cls.__instance = super().__new__(cls)
        return cls.__instance

def func():
    a = A()
    print(a)
from threading import Thread
for i in range(10):
    Thread(target=func).start()

以上是关于线程数据不安全现象的主要内容,如果未能解决你的问题,请参考以下文章

Linux:详解多线程(线程安全互斥和死锁)

Java并发多线程编程——集合类线程不安全之HashMap的示例及解决方案

为啥基于锁的程序不能组成正确的线程安全片段?

Java并发多线程编程——集合类线程不安全之HashSet的示例及解决方案

markdown 线程安全相关片段

Java并发多线程编程——集合类线程不安全之ArrayList的示例及解决方案