![]() |
1
8
问题是当你读到那个状态,然后做些什么的时候。写作是一条红鲱鱼——的确,只要这是一个单词,大多数环境都会保证写作是原子的,但这并不意味着包含此片段的较大代码片段是线程安全的。首先,假设您的全局变量包含一个不同的开始值-否则,如果您知道它总是相同的,为什么它是一个变量?第二,也许你最终 阅读 这个值又回来了? 问题可能是,你写这段共享状态是有原因的——是为了表明发生了什么事?这就是问题的症结所在:当没有锁结构时,根本就没有隐含的内存访问顺序。很难指出这里的错误,因为您的示例实际上不包含 使用 关于这个变量,这里有一个类似于中性C的语法的小例子:
线程A总是打印1,但线程B打印0是完全有效的。线程A中的操作顺序只需要从线程A中执行的代码中可以观察到-线程B可以看到状态的任何组合。对x和y的写入可能实际上不是按顺序进行的。 即使在单处理器系统上也可能发生这种情况,因为大多数人不希望这种重新排序—编译器可能会为您重新排序。在SMP上,即使编译器不重新排序,内存写入也可能在不同处理器的缓存之间重新排序。 如果这似乎不能回答你的问题,在问题中包括你的例子的更多细节。如果没有变量的使用,就不可能确定这样的使用是否安全。 |
![]() |
2
2
这取决于该声明实际完成的工作。仍然有一些情况发生,例如,如果C++类重载了=运算符,并在该语句中做任何非平凡的事情。 我无意中用pod类型(内置的原始类型)编写了这样的代码,它运行得很好——但是,这绝对不是一个好的实践,而且我不相信它是可靠的。 当你使用这个变量的时候,为什么不把它的内存锁起来呢?事实上,如果您不知何故“知道”这是代码中唯一可能在某个时刻出现的write语句,为什么不直接使用值11,而不是将其写入共享变量? ( 编辑: 我想最好用一个固定的名字而不是 magic number (顺便说一句,直接在法典中) 如果您使用这个来计算至少一个线程何时到达这个语句,那么您可以使用从1开始的信号量,并由第一个到达它的线程递减。 |
![]() |
3
1
我预计结果不会确定。因为不同的编译器,不同的语言,不同的操作系统,不同的操作系统等等,所以不,它是不安全的。 但是,为什么要这样做呢-添加一行代码来获取互斥锁(在大多数语言中都是一行或两行代码),这将消除任何可能出现的问题。如果这是两个昂贵的,那么你需要找到另一种解决问题的方法 |
![]() |
4
1
一般来说,除非您的系统提供原子操作(保证在一个周期内执行的操作),否则这被认为是不安全的。 原因是,虽然“c”语句看起来很简单,但通常会发生一些底层的汇编操作。 根据你的操作系统,你可以做一些事情:
|
![]() |
5
1
这是我对这个问题的看法。 您有两个或多个线程正在运行,这些线程向变量写入数据……比如状态标志之类的,您只想知道其中一个或多个线程是否为真。然后在代码的另一部分(线程完成后),您要检查并查看是否至少在线程上设置了该状态…例如
我相信上面的代码是可以的,假设您可以不知道哪个线程将状态设置为true,并且您可以在读取该标志之前等待所有多线程的工作完成。但我可能错了。 |
![]() |
6
0
假设这个属性除了11个之外永远不会被分配,那么我一开始就看不到分配的理由。那就把它定下来。 只有当您打算更改值时,assignment才有意义 除非 行为本身也有其他副作用,比如易失性写在Java中具有内存可见性的副作用。如果更改多个线程之间的共享状态,则需要同步或“处理”并发问题。 如果在没有正确同步的情况下,为多个线程之间共享的某个状态分配一个值,则无法保证其他线程何时会看到该更改。没有可见性保证意味着其他线程可能 从未 见分配人。 编译器,jit,cpu缓存。他们都在试图让你的代码尽可能快的运行,如果你对内存可见性没有任何明确的要求,那么他们会利用这一点。如果不在你的机器上,那就找别人。 |
![]() |
7
-1
如果手术是原子的,你 应该 能过得很好。但实际上我不会那样做。最好在对象上获取一个锁并写入值。 |
![]() |
user107586 · 如何处理等待句柄不会导致无限循环? 5 月前 |
![]() |
ron burgundy · 获取-释放语义是否跨线程传递?[副本] 5 月前 |
![]() |
BenjiFB · C#内存缓存:在一次操作中追加到列表? 5 月前 |
![]() |
András Takács · Python多线程问题 9 月前 |
|
András Takács · Python多线程错误 9 月前 |