用于共享内存环境的C中的相互排除实现

时间:2014-05-03 15:41:41

标签: c multithreading mutex shared-memory producer-consumer

我想实现(C)基于共享内存的通信生产者/消费者机制。它取代了客户端和远程服务器之间的流套接字通信。网络中的节点共享一个内存池,以便彼此通信。服务器可以在内存区域中写入数据(生成),客户端应该读取它(使用)。 我的软件实际上使用一个线程进行读取(客户端)和一个用于写入的线程(服务器端)。线程驻留在不同的机器上(分布式)。

实现互斥以访问共享内存区域的最佳和最快方法是什么? (内存在两台机器外部,只是提到) 如果客户端没有读取,服务器应该自动生成数据(写入);如果服务器没有写入,客户端应该原子地使用数据(读取)。

很明显我需要一种类似于线程的互斥机制。在这种情况下,线程等待通过本地内核中断解锁。 一个phthread实现是否也适用于这个分布式场景(锁定变量放在共享内存中 - 选项PTHREAD_PROCESS_SHARED设置)?

如何以不同方式实现快速可靠的互斥锁,使客户端线程和服务器线程依次访问共享区域,确保数据一致性?

1 个答案:

答案 0 :(得分:0)

所以简短的回答是:只要pthreads了解您的特定系统,就可以使用pthread互斥机制。否则,您需要查看特定的硬件/操作系统以获取帮助。

这个长的答案会有点笼统,因为这个问题没有提供有关正在使用的分布式共享内存的确切实现的大量细节。我将尝试解释可能的,但 如何执行它将依赖于实现。

正如@Rod建议的那样,生产者 - 消费者系统可以使用一个或多个互斥锁来实现,问题是如何实现互斥锁。

可以将互斥锁视为具有两种状态{LOCKED,UNLOCKED}和两个原子操作的对象:

  • 锁定:如果状态为LOCKED,则阻止直到UNLOCKED。将状态设置为LOCKED并返回。
  • 解锁:将状态设置为UNLOCKED并返回。

通常,操作系统内核通过在抽象互斥对象上实现这些操作来提供互斥锁。例如,Unix的某些变体将互斥锁和信号量实现为文件描述符上的操作。在这些系统上,pthreads将使用内核工具。

这种方法的优点是用户空间程序不必关心它是如何实现的。缺点是每个操作都需要调用内核,因此与下一个选项相比它可能相对较慢:

互斥锁也可以实现为存储位置(比如说长1个字节),它存储值0或1以指示UNLOCKED和LOCKED。可以使用标准内存读/写指令访问它。我们可以使用以下(假设的)原子操作来实现锁定和解锁:

  1. 比较和设置:如果内存位置的值为0,则将其设置为值1,否则将失败。
  2. 条件等待:阻止,直到内存位置的值为0。
  3. 原子写入:将内存位置设置为值0。
  4. 一般来说,#1和#3是使用特殊的CPU指令实现的,#2需要一些内核支持。这几乎就是How pthread_mutex_lock is implemented

    这种方法提供了速度优势,因为只有在互斥锁被争用(其他人拥有锁定)时才需要内核调用。