Is read/recv thread safe (MSG_PEEK)

I have one thread that is doing a blocking read:

rec = read(socket, data, size);

I'm curious to know whether it is safe or not for me to have another thread, doing recv(MSG_PEEK) in the background on the same socket:

while (true)
{
   if (recv(socket, byte, size, MSG_DONTWAIT | MSG_PEEK) > 0)
   {
       printf("peeked %d", byte);
   }
   sleep(1);
}

Upvotes: 4

Views: 634

Answers (1)

haneefmubarak
haneefmubarak

Reputation: 2051

Since syscalls operate in kernel space, they are thread safe (they have to be, otherwise kernel data could get corrupted and bring down your entire system) in the sense that your program won't crash - HOWEVER, as noted by Jeremy Friesner in the comments:

  • The order in which your syscalls are executed may not necessarily be guaranteed.

  • syscalls take time. This means that a lot of data will slip past in between your calls to recv ().


However, you could definitely write the bytes into a named FIFO. Open the writing end in the thread doing the read () and the reading end in the thread doing the recv ().

Now, every time you successfully complete a read (), write the first byte (that's all you wanted, yeah?) into the FIFO. Meanwhile, in the other thread, instead of using sleep () in between the recv (), just use a blocking read of size 1 byte on the FIFO and printf () the result.

This way, the kernel can automatically wake up your recv () thread whenever there is data to be read. You don't waste any CPU time with unnecessary context switches either (which are actually pretty big), so your application's overall performance/speed will go up too.

Upvotes: 1

Related Questions