|
|
1
1
一般来说,线程可能在不同的CPU/内核上运行,具有不同的内存缓存。它们可能在同一个内核上运行,其中一个中断(“先发制人”另一个)。这有两个后果: 1)您无法知道在执行某项操作的过程中,一个线程是否会被另一个线程中断。因此,在您的示例中,无法确保thread1在thread2写入字符串值之前不会尝试读取该字符串值,或者甚至当thread1读取字符串值时,它处于“一致状态”。如果它不处于一致状态,那么使用它可以做任何事情。 2)当您在一个线程中写入内存时,不知道在另一个线程中运行的代码是否或何时会看到这种变化。更改可能位于编写器线程的缓存中,不会刷新到主内存中。它可能会被刷新到主内存中,但不会进入读线程的缓存中。一部分的变化可能会使它过去,而另一部分则不会。 一般来说,如果没有锁(或其他同步机制,如信号量),就无法判断线程A中发生的某些事情是在线程B中发生的“之前”还是“之后”发生。也无法判断线程A中所做的更改是在线程B中“可见”还是何时“可见”。 正确使用锁可以确保所有更改都通过缓存刷新,这样代码就可以看到您认为应该看到的内存状态。它还允许您控制特定的代码位是否可以同时运行和/或相互中断。 在这种情况下,查看上面的代码,您需要的最小锁定是拥有一个同步原语,该原语在第二个线程(编写器)编写完字符串后由它释放/发布,在使用该字符串之前由第一个线程(读卡器)获取/等待。这样可以保证第一个线程看到第二个线程所做的任何更改。 假设在调用firstFunctionRunFromThread1之后才启动第二个线程。如果情况并非如此,那么您需要同样处理线程1写入和线程2读取。 实际上,最简单的方法是使用一个互斥体来“保护”您的数据。您可以决定要保护哪些数据,而任何读取或写入数据的代码在执行此操作时都必须保持互斥。因此,首先锁定,然后读取和/或写入数据,然后解锁。这确保了状态的一致性,但它本身并不能确保thread2在thread1的两个不同功能之间有机会做任何事情。 任何类型的消息传递机制都会包含必要的内存屏障,因此,如果您从编写线程向读线程发送消息,意思是“我已经完成了写,您现在可以阅读”,那么这是正确的。 如果某些事情被证明太慢,那么可以有更有效的方法来做。 |
|
|
2
2
一个函数(即线程)修改映射,两个函数读取映射。因此,读操作可能被写操作中断,反之亦然,在这两种情况下,映射都可能被破坏。你需要锁。 |
|
|
3
2
事实上,不仅仅是锁定问题… 如果您真的希望线程2总是打印“test 1”,那么您需要一个条件变量。 原因是有一个种族条件。无论您是否在线程2之前创建线程1,线程2的代码都有可能在线程1之前执行,因此映射不会正确初始化。为了确保在初始化映射之前没有人读取它,您需要使用线程1修改的条件变量。 正如其他人提到的,您还应该对映射使用锁,因为您希望线程访问映射,就好像它们是唯一使用它的线程一样,并且映射需要处于一致状态。 下面是一个概念性的例子来帮助您思考它: 假设您有一个链接列表,2个线程正在访问该列表。在线程1中,您要求从列表中删除第一个元素(在列表的开头),在线程2中,您尝试读取列表的第二个元素。 假设delete方法是通过以下方式实现的:使一个临时ptr指向列表中的第二个元素,使head指向空值,然后使head成为临时ptr… 如果发生以下事件序列会怎样? -T1删除第二个元素的ptr旁边的heads -t2尝试读取第二个元素,但没有第二个元素,因为头部的下一个ptr已被修改。 -T1完成移除头部并将第二个元件设置为头部 t2的读取失败,因为t1没有使用锁使从链接列表中删除的内容成为原子! 这是一个做作的示例,不一定是如何实现删除操作;但是,它说明了为什么需要锁定:必须这样才能对数据执行原子操作。您不希望其他线程使用不一致的状态。 希望这有帮助。 |
|
|
4
1
|
|
|
5
0
由于编译代码而创建的指令集可以按任意顺序交错。这会产生不可预测和不期望的结果。例如,如果在选择运行thread2之前运行thread1,则输出可能如下所示:
更糟糕的是,如果分配不是一个 原子的 操作。在这种情况下,让我们想想 原子的 作为最小的工作单位,不能进一步拆分。 为了创建逻辑上原子化的指令集——即使它们实际上产生了多个机器代码指令——就是使用 锁 或 互斥 . mutex代表“互斥”,因为它就是这样做的。它确保对某些对象的独占访问,或者 关键部分 代码的。 处理多道程序设计的主要挑战之一是确定 关键部分。 在本例中,有两个关键部分:分配给mymap的位置和更改mymap的位置[0]。既然你不想 阅读 我的地图在写之前,就是 也 关键部分。 |
|
|
6
0
最简单的答案是:只要有权访问某些共享资源(而不是原子),就必须锁定。在你的情况下
|
|
|
JLosc · Powershell脚本因文件锁定而失败 1 年前 |
|
|
Sriram Umapthy · PostgreSql行级锁 1 年前 |
|
|
a a · 为什么在这个可重入锁示例中需要引用计数? 3 年前 |
|
|
JohnLBevan · 为什么原子语句上需要锁提示? 7 年前 |