无信号量的共享内存访问

发布于 2024-08-06 05:24:41 字数 105 浏览 11 评论 0原文

在linux中使用共享内存api,如果我有一次写入(由A进程)并且只有一次读取(由B进程),我还需要信号量吗?? 有没有例子可以说明,在没有信号量的情况下使用共享内存会在linux中陷入死锁状态。

using shared memory apis in linux, If I have one write(by A process) and only one read( by B process) do I still need semaphore.?.
Is there a example to show, using sharing memory without semaphore will get into deadlock state in linux.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

岁吢 2024-08-13 05:24:41

你的问题有点奇怪。首先,您不需要使用信号量,因为还有其他同步方法。

其次,不使用信号量通常不会导致死锁(除非您出于某种原因使用信号量保护锁或其他同步方法)。使用同步方法往往会导致死锁,而不是不使用同步方法。

但是,当作者和读者争夺同一资源时,您可以拥有所谓的 竞争条件

现在,针对一位作者和一位读者的问题:这可以使用互斥体而不是信号量或任何其他数量的同步方法来完成。或者,如果您可以保证 B 进程的写入是原子的(即,如果中断,它们不会使共享内存处于不一致状态),则不需要同步。后一种情况不太可能发生,除非可以通过单个指令更新共享内存(有时甚至这还不够)。您最好采取安全路线并以某种方式锁定对共享内存的访问。

Your question is a bit strange. First of all you don't NEED to use semaphores, as there are other methods of synchronization.

Second, not using a semaphore isn't going to usually cause a deadlock (unless you had a semaphore protecting a lock or other synchronization method for some reason). The USE of synchronization methods tend to cause deadlocks, not the absence of them.

However when you have writer(s) and reader(s) contending for the same resource, you can have what is known as a Race Condition

Now for your question of one writer and one reader: This can be done with mutexes instead of semaphores or any other number of sychronization methods. Alternatively, if you can guarantee that B process's writes are atomic (ie they can not leave the shared memory in an inconsistent state if interrupted), then no synchronization is needed. The latter scenario is very unlikely unless the shared memory can be updated by a single instruction (and sometimes even that's not enough). You'll be better off just taking the safe route and locking access to the shared memory in someway.

淡写薰衣草的香 2024-08-13 05:24:41

如果没有信号量(或者更一般地说是 MUTEX),就不会出现死锁。然而,可能发生的情况是数据不一致/不连贯。

例如,如果在共享内存位置中找到的对象类型是表示文本字符串的字符数组。一个线程可能开始修改该字符串,而另一个线程读取该字符串一次,并收到一条奇怪的消息。

For example:
Original text
    "The British are coming!"
Thread 1 start changing to "Warn all patriots!" but only gets to write the 
first 8 characters.  Then...
Thread 2 reads
    "Warn allish are coming!

编辑:请参阅 Falaina 的响应,该响应通常与此相呼应,并提供了相关概念的指针和定义:竞争条件、原子性、互斥......

Without semaphores (or more generally MUTEX) there cannot be deadlocks. What may happen however is inconsistent/incoherent data.

For example if the types of objects found in the shared memory location are char arrays representing text strings. It may be possible for one thread to start modifying the string and another thread to read it a once, getting an odd message.

For example:
Original text
    "The British are coming!"
Thread 1 start changing to "Warn all patriots!" but only gets to write the 
first 8 characters.  Then...
Thread 2 reads
    "Warn allish are coming!

Edit: See Falaina's response which generally echoes this one, and provides pointers and defintions to related concepts: race conditions, atomicity, mutex...

娇纵 2024-08-13 05:24:41

只有一个进程写入时,您将无法陷入死锁。

然而,读者必须能够在阅读时处理部分写入的数据。这很可能是不可能的。

另外,当您说一个在写,一个在读时,您真的指的是只读吗?如果您指的是管道,其中一个进程将内容放入管道,另一个进程从管道中删除内容,那么实际上两个进程都在写入共享内存。

With only one process writing you won't be able to get into a dead-lock.

However the reader would have to be able to deal with partially written data while reading. And that might well be impossible.

Also when you say one is writing and one reading, do you really mean read-only. If you mean a pipe, where one process puts things on the pipe, and the other removes things from the pipe, then really both are writing to the shared memory.

九八野马 2024-08-13 05:24:41

当您访问共享内存时(除非您只读取),您需要防止并发写入或写入期间读取。正确的方法是使用信号量。

您可以使用此 ScopedLock 类作为您的锁机制,只有一个进程可以同时拥有具有特定名称的作用域锁。如果另一个进程尝试创建它,它将被阻止,直到第一个进程范围锁超出范围。

#include <semaphore.h>
class ScopedLock{
    sem_t *sem;
public:
    ScopedLock(const char* name) : sem(0)
    {
        sem = sem_open(name, O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, 1);
        if (sem == SEM_FAILED)
        {
            printf("Error opening semaphore : %s\n", last_error_message());
            throw "failed to create semaphore";
        }

        printf("locking interprocess lock...\n");
        if (-1 == sem_wait(sem))
        {
            printf("Error locking semaphore : %s\n", last_error_message());
            throw "failed to lock semaphore";
        }
        printf("interprocess lock locked\n");
    }

    ~ScopedLock()
    {
        if (sem)
        {
            sem_post(sem);
            printf("interprocess lock unlocked\n");
        }
    }

    // static destroy function, use for cleanup
    static void destroy(const char *name)
    {
        sem_t *sem = sem_open(name, O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
        if (sem != SEM_FAILED)
        {
            sem_post(sem);
            sem_destroy(sem);
        }

        if (-1 == sem_unlink(name))
        {
            printf("Error destroying semphore: %s\n", last_error_message());
        }
    }
};

when you access shared memory (unless you only read) you need to protect against concurrent writes or read during write. the proper way to do it is to use semaphores.

You can use this ScopedLock class as your lock mechanism, only one process can own a scoped lock with a particular name at the same time. if another process will try to create it, it will be blocked until the first process scoped lock gets out of scope.

#include <semaphore.h>
class ScopedLock{
    sem_t *sem;
public:
    ScopedLock(const char* name) : sem(0)
    {
        sem = sem_open(name, O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, 1);
        if (sem == SEM_FAILED)
        {
            printf("Error opening semaphore : %s\n", last_error_message());
            throw "failed to create semaphore";
        }

        printf("locking interprocess lock...\n");
        if (-1 == sem_wait(sem))
        {
            printf("Error locking semaphore : %s\n", last_error_message());
            throw "failed to lock semaphore";
        }
        printf("interprocess lock locked\n");
    }

    ~ScopedLock()
    {
        if (sem)
        {
            sem_post(sem);
            printf("interprocess lock unlocked\n");
        }
    }

    // static destroy function, use for cleanup
    static void destroy(const char *name)
    {
        sem_t *sem = sem_open(name, O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
        if (sem != SEM_FAILED)
        {
            sem_post(sem);
            sem_destroy(sem);
        }

        if (-1 == sem_unlink(name))
        {
            printf("Error destroying semphore: %s\n", last_error_message());
        }
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文