Linux上的C语言中的POSIX线程和全局变量

时间:2012-03-14 06:23:11

标签: c linux multithreading

如果我有两个线程和一个全局变量(一个线程不断循环读取变量;另一个不断循环写入它)会发生什么事情不应该? (例如:例外,错误)。如果它,是什么方法来防止这种情况。我正在阅读有关互斥锁的内容,并且它们允许对一个线程的变量进行独占访问。这是否意味着只有那个线程可以读写它而不能读取它?

5 个答案:

答案 0 :(得分:3)

  

有什么事情不应该发生吗?

部分取决于变量的类型。如果变量是一个字符串(长字符数组),那么如果作者和读者同时访问它,那么读者将看到的内容是完全未定义的。

这就是pthreads提供互斥和其他协调机制的原因。

  

这是否意味着只有那个线程可以读写它而不能读取它?

互斥锁确保使用互斥锁的一个线程最多可以有权继续。使用相同互斥锁的所有其他线程将被保留,直到第一个线程释放互斥锁。因此,如果代码写得正确,任何时候,只有一个线程能够访问该变量。如果代码编写不正确,那么:

  • 一个线程可以访问变量而不检查它是否有权这样做
  • 一个线程可能获取互斥锁并且永远不会释放它
  • 一个线程可能会破坏互斥锁而不通知另一个

这些都不是理想的行为,但仅仅存在互斥体并不能阻止任何这些行为发生。

尽管如此,您的代码可以合理地合理使用互斥锁,然后可以正确控制对全局变量的访问。虽然它通过互斥锁具有权限,但是任何一个线程都可以修改变量,或者只是读取变量。要么安全,不受其他线程的干扰。

答案 1 :(得分:2)

这是否意味着只有该线程可以读写它而不能读取其他内容?

这意味着一次只有一个线程可以读取或写入全局变量 这两个线程之间不会 race 来访问全局变量,也不会在任何给定的时间点同时访问它。

简而言之,对全局变量的访问是 Synchronized

答案 2 :(得分:0)

首先;在C / C ++中,变量的非同步读/写不会产生任何异常或系统错误,但它可以生成应用程序级错误 - 主要是因为您不太可能完全理解如何访问内存,以及它是否是原子的,除非你看一下生成的汇编程序。当您在没有同步的情况下访问共享内存时,多核CPU可能会创建难以调试的竞争条件。

因此

二;在处理共享内存时,应始终使用同步 - 例如互斥锁。互斥锁很便宜;如果做得好,它不会真正影响性能。经验法则;保持lcok尽可能短,例如在读取/递增/写入共享内存期间。

然而,根据你的描述,听起来你的一个线程没有做什么但是等待共享的meory在做某事之前改变状态 - 这是一个糟糕的多线程设计,这会花费不必要的CPU刻录,所以< / p>

第三;如果您尝试从一个线程向另一个线程发送“消息”,请查看使用信号量(sem_create / wait / post)进行线程之间的同步

答案 3 :(得分:0)

正如其他人已经说过的,当通过“普通”对象在线程之间进行通信时,你必须处理竞争条件。除了互斥锁和其他相对较重的锁定结构外,新的C标准(C11)提供了原子类型和操作,保证无竞争。大多数现代处理器都为这些类型提供了指令,许多现代编译器(特别是Linux上的gcc)已经为这些操作提供了适当的接口。

答案 4 :(得分:-1)

如果线程真的只是一个生产者而且只有一个消费者,那么(除了编译器错误)然后

1)将变量标记为volatile,

2)确保它正确对齐,以避免交错的提取和存储

允许您在不锁定的情况下执行此操作。