2008-10-30 78 views
5

我有一个单一的HW接口我想从在同一工作站上的两个应用程序(过程)的使用。硬件需要一次初始化调用,然后两个应用程序使用同一个函数(在同一个库中)与HW进行许多事务。如何同步两个进程?

因此,每个应用程序应该像这样:

main() 
    // I don't know if another app already init'ed the HW 
    ret = hw_init_lock(non-blocking) 

    if ret = OK 
     // no one else has done this, I have to 
     init_hw() 
    else 
     //someone else has already init'ed the HW, I gotta make sure it stays that way 
     //as long as I'm alive 
     increment_hw_init_ref_counter() 

    hw_trans_lock(blocking) 
    hw_trans() 
    hw_trans_unlock() 
    .... 

    //exit app, uninit hw if we are last out 
    ret = decrement_hw_init_ref_counter() 
    if ret == 0 
     uninit_hw() 

    exit(0) 

什么机制我可以是两个应用程序之间共享锁和引用计数呼叫使用?我在想命名管道,即mkfifo()。

回答

2

因为你只需要一个信号计数,互斥就足够了。

+4

POSIX信号可以在不相关的进程共享,同时并行线程互斥不能。 – ephemient 2008-10-31 00:12:30

9

POSIX semaphore是要走的路。既然你想分享整个过程相同的信号,你需要使用一个命名信号量:

命名信号量是查明的形式/ somename的 名。两个 过程可以通过将相同 名sem_open(3)在同一 命名信号量操作。

1

我认为

...这是两个应用程序之间共享?

表示您希望这两件事情作为单独的进程运行?如果这是不正确的,他们正在运行的一个进程(多线程),那么信号量和互斥的建议是最好的选择,应该是很简单的。

请注意,答案将取决于您如何访问此硬件。例如,如果它通过文件公开,那么可以使用正常的文件锁定。

但是,如果您试图通过两个进程来同步对硬件的访问,这是另一回事。 我猜说的第一件事是,它会更容易,如果你能同步,有负责访问硬件的一个过程。在这个模型中,您可能有一个进程充当硬件的服务器 - 接受来自其他进程的请求并代表他们执行读取和写入操作。几乎任何形式的进程间通信都是合适的,但为了简单起见,类似于消息队列(link)的某些适当的数据结构(例如,用于指示它是读取还是写入操作的标志,与基地址的偏移您的硬件,字节数,缓冲区(在写入的情况下))

如果将所有直接硬件访问放入单个进程并不合适,那么您必须使用适当的同步方案。我会研究使用任何文件锁(并实现一个基本的互斥体方案)或使用命名信号量(如albertb建议)

4

信号量和互斥/条件变量是很好的,非常高性能的基元用于线程之间或进程之间。

所有这些都基于对共享内存执行的测试和设置或其他原子操作的想法(通常是在现实中)。

如果您希望通过网络分发您的进程,那么信号量和互斥量可能并不适合您 - 它们只能在单台计算机上运行。管道和套接字通常更具网络可扩展性。

互斥,条件变量和信号量的简要概述:

互斥

互斥是一种原始其可以是锁定,或解锁。锁定它的进程/线程必须是解锁它的进程/线程。这个的所有权方面允许操作系统应用一些有趣的优化,例如优先级继承和优先级上限协议(以避免优先级倒置)。然而,,互斥量没有与其关联的计数。不能锁定一个已经锁定的互斥体,一般来说,并保留记忆,这是“锁定两次”(也有一些扩展,允许这一点,我想,但他们不是随处可得)

条件变量

互斥对于......好,MUTual排除很好。但是,如果您需要阻止与您互相排斥的对象相关的条件,该怎么办?为此,您使用条件变量或CV。简历与互斥体相关联。例如,假设我有一个我的进程想要访问的输入数据队列。一个人抓住互斥体,这样就可以在不用担心干扰的情况下查看队列。但是,它发现队列为空,并且想要等待队列中出现的内容。因此它等待“队列不空”条件变量。这里有趣的部分是,因为CV与互斥体相关联,一旦条件变量被发信号,互斥体获得自动重新获得。因此,一旦进程在等待CV后醒来,它知道它再次对队列进行独占访问。它的功能不是知道队列是否真的有什么东西 - 也许有两个进程等待在CV上 - 有一件事出现了 - 在第二件事醒来之前,第一优先进入并将队列出来向上。因此,无论你使用一个简历,你需要重新检查的条件,像这样:

mutex_enter(m); 
while (! condition) { 
    cond_wait(m, c); // drop mutex lock; wait on cv; reacquire mutex 
} 
//processing related to condition 
mutex_exit(m); 

信号灯

行,就是互斥体和条件变量。信号量更简单。它们可以通过任何进程递增和递减。他们有记忆 - 他们数 - 所以你可以用它们来确定发生了多少病症。与调节变量不同。另外,因为信号可以被一个进程递减并且被另一个进程递增,所以他们没有所有权方面 - 所以没有优先级继承,没有优先级反转回避是可能的。

现在,最后 - 所有这些机制都需要共享内存才能有效实施。这可能对你很好,但请注意 - 如果你认为你的应用程序最终可能被分发,那么互斥锁,条件变量和信号可能不适合你。虽然管道和插座的开销较高,但可能会相当直接地通过网络扩展。