【问题标题】:synchronization on linux, c/c++linux上的同步,c/c++
【发布时间】:2015-04-03 18:30:00
【问题描述】:

我将在 Linux 上同步两个不同的进程。两个进程都想访问一个设备,一个进程可以同时使用该设备。到目前为止,我一直在使用命名信号量进行同步,并且它运行良好,直到有人杀死了当前在设备上运行的进程。在这种情况下,信号量不会被释放,这会导致所有试图获取信号量/访问设备的进程挂起。

这可以在 Windows 下使用互斥锁简单解决。在这个系统中,当拥有的线程/进程终止时,命名的互斥锁会自动释放。

我将感谢 Linux 上的所有 cmets 和/或解决方案。

提前致谢! 托雷诺

【问题讨论】:

  • 即使Linux进程被杀死,它是否也不会得到WM_CLOSE的等价物?当然,它会收到 some 信号(除非被 kill -9 或其他什么杀死(我完全忘记了 Linux 是如何工作的,但在没有警告的情况下杀死似乎不太可能))
  • 你听说过 C++ RAII 成语stackoverflow.com/questions/2321511/…吗?它将帮助您自动关闭/释放您想要的任何东西。
  • 阅读Advanced Linux Programming;同步的方式有很多种(sem_overview(7)flock(2)等......)
  • solution here 建议文件锁定....

标签: c++ linux synchronization


【解决方案1】:

正如 Tony D 在之前的评论中建议的那样,我使用羊群解决了这个问题。如果将来有人想使用它,这是我的代码:)

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

class CriticalSection
{
    private:

        char fileName[FILENAME_MAX];
        int fileDescriptor;


    public:

        CriticalSection(const char *sectionName)
        {
            // Mark as not acquired
            fileDescriptor = -1;

            // Build file name path
            snprintf(fileName, sizeof(fileName), "/tmp/.%s", sectionName);
        }

        ~CriticalSection()
        {
            // Release critical section on object deletion
            release();
        }

        void acquire()
        {
            // Test if section is already acquired
            if(fileDescriptor != -1)
                return;

            // Acquire critical section
            fileDescriptor = open(fileName, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); 
            if(fileDescriptor != -1)
                lockf(fileDescriptor, F_LOCK, 0);
        }

        void release()
        {
            // Release critical section
            if(fileDescriptor != -1) {
                close(fileDescriptor);
                fileDescriptor = -1;
            }
        }
};

int main()
{
    // Create critical section
    CriticalSection cs("myappname");

    // Enter crtitical section
    cs.acquire();

    // Critical section code
    printf("Critical section has been acquired successfully!\n");

    // Leave critical section
    cs.release();
    return 0;
}

玩得开心, 托雷诺

【讨论】:

  • 当然,也可以通过在构造函数的最后一行调用acquire()函数来简单地修改为提供RAII。
  • 最后不需要cs.release(),因为析构函数会被自动调用(因为cs在堆栈上)。这将只留下 3 行代码:构造 csprintfreturn,但您会收到来自编译器的 unused variable 警告。
猜你喜欢
  • 2020-07-29
  • 2023-03-13
  • 1970-01-01
  • 2019-09-28
  • 2013-10-25
  • 1970-01-01
  • 2018-12-08
  • 2012-04-30
  • 1970-01-01
相关资源
最近更新 更多