数据共享之共享数据带来的问题

改动共享数据会给共享数据带来问题。假设共享的数据是仅仅读的话,就不会带来问题。

假设数据能够改动。有超过两个以上的线程改动数据就会带来问题。

必须用一些方法来消除问题。

资源竞争(race condition)

资源竞争是指在多线程环境下,程序结果的输出依赖于相关线程的运行顺序。英文:A race condition is anything where the outcome depends on the relative ordering of execution of operations on two or more threads; the threads race to perform their respective operations.

有些情况下。资源竞争情况下全部结果都能接受。比如,向链表加入结点。哪个线程先加入都无所谓。结果都是把结点加入上去了。

有时候资源竞争的结果不能接受。我们经常讲的资源竞争是指有问题的、结果不能接受的资源竞争。

C++标准中定义的数据竞争(data race)是资源竞争的一种特例。

当一个操作要改动多个不相关数据时,经常发生资源竞争。由于改动多个数据操作须要多个CPU指令,在此期间,其它线程可能訪问这些数据。资源竞争非常难发现。由于在资源竞争情况下也会出现正确结果。

避免资源竞争

避免资源竞争经常使用的办法是把数据包装起来。当包装被拆掉时,仅仅有当前正在改动数据的这个进程能够看到数据。在其它线程看来,要么改动还没開始,要么改动已经结束了。C++标准提供了这种机制。

还有一中办法是改动数据结构和变量,使得改动的指令是连续的、不可中断的。这叫做无锁编程(lock-free programing),比較难。

假设你在这个层次编程(working at this level),内存模型细微的改动都可能会使变量值变复杂。

另一种处理资源竞争的办法就是把更新数据的操作当做事物(transaction)。假设成功,都成功;假设失败则回滚,都失败。

在C++标准库中,保护共享数据的最主要的机制是相互排斥量(mutex)。

时间: 2024-10-06 11:46:33

数据共享之共享数据带来的问题的相关文章

【java并发】线程范围内共享数据

假设现在有个公共的变量data,有不同的线程都可以去操作它,如果在不同的线程对data操作完成后再去取这个data,那么肯定会出现线程间的数据混乱问题,因为A线程在取data数据前可能B线程又对其进行了修改,下面写个程序来说明一下该问题: public class ThreadScopeShareData { private static int data = 0;//公共的数据 public static void main(String[] args) { for(int i = 0; i

用 volume container 共享数据 - 每天5分钟玩转 Docker 容器技术(42)

volume container 是专门为其他容器提供 volume 的容器.它提供的卷可以是 bind mount,也可以是 docker managed volume.下面我们创建一个 volume container: 我们将容器命名为 vc_data(vc 是 volume container 的缩写).注意这里执行的是 docker create 命令,这是因为 volume container 的作用只是提供数据,它本身不需要处于运行状态.容器 mount 了两个 volume: b

在 App 扩展和主 App 间共享数据

tags: iOS 8,Swift,App Groups 随着 iOS 8 的发布,苹果为广大开发者很多新的 API,其中最突出显著的就非 App Extension 莫属了.这为开发者们又带来了很多机会. 而我们在开发 App Extension 的时候,基本大多数人都会遇到这样一个问题.就是由于 App Store 的规则是 App Extension 不能独立的发布,而是要跟随一个宿主应用一起发布. 比如奇妙清单: {% img figures /images/extension_1.jp

线程的创建 验证线程之间共享数据 守护线程 线程进程效率对比 锁 死锁 递归锁

线程(from threading import Thread):CPU调度的最小单位 线程的两种创建方式:方式一: 1 from threading import Thread 2 def f1(i): 3 print(i) 4 if __name__ == '__main__': 5 for i in range(10): 6 t = Thread(target=f1,args=(i,)) 7 t.start() 8 print('主线程') 方式二: 1 from threading im

40-用 volume container 共享数据

volume container 是专门为其他容器提供 volume 的容器.它提供的卷可以是 bind mount,也可以是 docker managed volume.下面我们创建一个 volume container: 我们将容器命名为 vc_data(vc 是 volume container 的缩写).注意这里执行的是 docker create 命令,这是因为 volume container 的作用只是提供数据,它本身不需要处于运行状态.容器 mount 了两个 volume: b

78.PL和PS通过BRAM交互共享数据

本篇文章目的是使用Block Memory进行PS和PL的数据交互或者数据共享,通过zynq PS端的Master GP0端口向BRAM写数据,然后再通过PS端的Mater GP1把数据读出来,将结果打印输出到串口终端显示. 涉及到AXI BRAM Controller 和 Block Memery Generator等IP的使用. 本系列文章尽可能的让每一个实验都相对独立,过程尽可能保证完整性,保证实验的可重现性. 但是用到的模块或者IP的具体作用和用法不保证都重复详细的介绍. 本文所使用的开

iOS应用程序间共享数据(转)

我们知道iOS由于沙盒的存在,应用程序不能越过自己的区域去访问别的存储空间的内容,不过可能有许多场景我们需要在应用程序之间共享数据,比如多个应用共用用户名密码进行登录等.虽然我们不能直接通过文件系统来分享数据,不过还是有些方法可以实现,为了方便说明,这里同时创建了两个工程Example1和Example2,实现这两个app之间的信息共享,Example1负责写数据,Example2负责读数据,具体的demo代码可以到这里获取 UIPasteboard 剪贴板是应用程序之间传递数据的简单方式,建议

不同App之间共享数据

我们知道iOS由于沙盒的存在,应用程序不能越过自己的区域去访问别的存储空间的内容,不过可能有许多场景我们需要在应用程序之间共享数据,比如多个应用共用用户名密码进行登录等.虽然我们不能直接通过文件系统来共享数据,不过还是有些方法可以实现. 这里,我们新建两个工程,T1:负责写数据,T2:负责读数据. 方法一:UIPasteboard 剪贴板是应用程序之间传递数据的简单方式,建议不要使用全局的粘贴板,而是自己根据名字创建一个新的粘贴板,防止其它地方全局拷贝的影响.然后把需要共享的内容复制到粘贴板,粘

多线程共享数据

线程间的数据共享 多个线程共享数据, A线程生产物品,产品数量增加,B线程使用,那么产品数量减少,B线程如何知道产品buf是否为空呢?A线程如何判断产品buf为满?1 轮询机制      线程每隔一定时间检查缓冲区,如果有产品就取出,这种机制需要控制好轮询间隔,查询太频繁会导致占用cpu过多,浪费:查询太不频繁导致缓冲区满,生产者放不进去产品  int buf[MAX];  int ProductionCount;  while(1)  {  Msleep(100);     if(Produc