【问题标题】:Communicating between threads without IPC没有IPC的线程间通信
【发布时间】:2013-12-23 16:49:17
【问题描述】:

考虑到我有两个线程:线程 1 和线程 2。 我只是想和他们交流。 线程 1 包含一个存储在指针中的值,线程 2 需要在该线程周围访问该指针值。

根据我的理解,我认为我们可以直接将指针从一个线程解引用到另一个线程。但是我朋友的建议是我只通过IPC机制访问值,而不是我的建议。

请对此发表评论。 最好的方法是什么,为什么...?

【问题讨论】:

  • 两个罐子中间有一根绳子怎么样? ;-)
  • 顺便说一句,您可能会使用线程之间的同步,而不是进程之间的通信!由于线程共享一个公共地址空间,因此通信是“免费的”......

标签: c linux multithreading


【解决方案1】:

两个线程可以访问同一个变量,这很好。请注意synchronization issues。如果两个线程都写入该值,则有可能出现race condition。如果任一线程写入值non-atomically(这样数据的值不会始终处于一致状态),则其他线程可能会在其处于无效中间状态时读取该值。这些情况需要使用mutexessemaphores 等同步原语来处理。

【讨论】:

  • 那真是太好了。但是考虑这样一种情况,即 THREAD 1 将值写入指针而 THREAD 2 只读取它。在这种情况下,我的建议会奏效吗?
  • 在那种情况下有一个问题 what 的值是,如果它是一个复杂类型的指针,你可能会发现部分写入状态(是你的写入 atomic) 简单地使用互斥锁来同步对资源的访问会更安全。通常,如果您有一个复杂类型,您可以将互斥体 添加到您的类型,结构的另一个成员,并对其进行操作,而无需传递第二个指针。
  • @RajanChennai:只有并发读取操作在没有同步的情况下是安全的!
【解决方案2】:

阅读好posix threads tutorial。然后您就会明白为什么在实践中使用同步原语如此重要(至少要从您的程序中获得可理解的行为)。

任何数据都可以在线程之间共享,因为它们都共享同一个公共address space。但是,您确实想要同步此类共享访问(因为如果没有显式同步,您无法知道一个线程何时看到另一个线程完成的更改;请阅读cache coherence)。一种常见的方法是为此使用mutexes

稍微解释一下,用你的共享全局数据声明一个全局互斥锁:

pthread_mutex_t glob_mtx = PTHREAD_MUTEX_INITIALIZER;
static struct globaldata_st glob_data;

然后,要访问一些数据,例如

int sharednumber;
pthread_mutex_lock(&glob_mtx);
sharednumber = glob_data.number;
pthread_mutex_unlock(&glob_mtx);

为了原子地更新数据,增加它:

int sharednumber;
pthread_mutex_lock(&glob_mtx);
sharednumber = glob_data.number++;
pthread_mutex_unlock(&glob_mtx);

您将类似地序列化更新或对共享链表队列的访问等......

不要羞于使用互斥锁,它们是quite fast。始终将 pthread_mutex_lockpthread_mutex_unlock 配对 ....

请记住,同步错误很难找到,因为它们不可重现:它们是 heisenbugs

在 Linux/x86-64 上使用 GCC 4.8,您可以使用 thread sanitizergcc -Wall -fsanitize=thread -g 来简化调试。

【讨论】:

    猜你喜欢
    • 2011-08-25
    • 1970-01-01
    • 2011-02-10
    • 2011-03-22
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多