views:

392

answers:

4

Hi All, 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.

+1  A: 

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...

mjv
A: 

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.

Douglas Leeder
A: 

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());
     }
    }
};
Omry
Doesn't it become a mutex implementation at that point then?
Justin Niessner
+2  A: 

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.

Falaina
Thanks a lot for all your inputs. struct sharedStruct { bool isOk; }; My requirement for sure I am going to have one process to read(isOK) and another process going to update (isOK) both in while loop. During read, I am OK with whatever state of the variable(true or false). I even executed multiple copies of process B( write isOK ) and see no issues.Just want to understand what extra code is MUST required to prevent odd behavior..(race condition, etc) and how to get into that weird state.
newbie