whh4000
whh4000

Reputation: 955

Mutexs with pipes in C

I am sorry if this sounds like I am repeating this question, but I have a couple additions that I am hoping someone can explain for me.

I am trying to implement a 'packet queueing system' with pipes. I have 1 thread that has a packet of data that it needs to pass to a second thread (Lets call the threads A and B respectively). Originally I did this with a queueing structure that I implemented using linked lists. I would lock a Mutex, write to the queue, and then unlock the Mutex. On the read side, I would do the same thing, lock, read, unlock. Now I decided to change my implementation and make use of pipes (so that I can make use of blocking when data is not available). Now for my question:

Do I need to use Mutexs to lock the file descriptors of the pipe for read and write operations?

Here is my thinking.

I have a standard message that gets written to the pipe on writes, and it is expected to be read on the read side.

 struct pipe_message {
    int stuff;
    short more_stuff;
    char * data;
    int length;
 };

 // This is where I read from the pipe
 num_bytes_read = read(read_descriptor, &buffer, sizeof(struct pipe_message));
 if(num_bytes_read != sizeof(struct pipe_message))  // If the message isn't full
 {
      printe("Error: Read did not receive a full message\n");
      return NULL;
 }

If I do not use Mutexs, could I potentially read only half of my message from the pipe? This could be bad because I would not have a pointer to the data and I could be left with memory leaks.

But, if I use Mutexs, I would lock the Mutex on the read, attempt to read which would block, and then because the Mutex is locked, the write side would not be able to access the pipe.

Upvotes: 0

Views: 3592

Answers (2)

Ian Puleston
Ian Puleston

Reputation: 31

Using a mutex with a blocking pipe is actually dangerous. If the write side takes the mutex, writes to the pipe and blocks because the pipe is full, then the read side can't get the mutex to read the data from the pipe, and you have a deadlock.

To be safe, on the write side you'd probably need to do something like take the mutex, check if the pipe has space for what you want to write, if not then release the mutex, yield and then try again.

Upvotes: 0

bazza
bazza

Reputation: 8394

Do I need to use Mutexs to lock the file descriptors of the pipe for read and write operations?

It depends on the circumstances. Normally, no.

Normality

If you have a single thread writing into the pipe's write file descriptor, no. Nor does the reader need to use semaphores or mutexes to control reading from the pipe. That's all taken care of by the OS underneath on your behalf. Just go ahead and call write() and read(); nothing else is required.

Less Usual

If you have multiple threads writing into the pipe's write file descriptor, then the answer is maybe.

Under Linux calling write() on the pipe's write file descriptor is an atomic operation provided that the size of data being written is less than a certain amount (this is specified in the man page for pipe(), but I recall that it's 4kbytes). This means that you don't need a mutex or semaphore to control access to the pipe's write file descriptor.

If the size of the data you're writing is too large then then the call to write() on the pipe is not atomic. So if you have multiple threads writing to the pipe and the size is too large then you do need a mutex to control access to the write end of the pipe.

Upvotes: 1

Related Questions