读/ recv线程安全(MSG_PEEK)

时间:2015-04-22 18:35:19

标签: c multithreading sockets unix

我有一个线程阻塞read

rec = read(socket, data, size);

我很想知道我是否有另一个线程是安全的,在同一套接字的后台执行recv(MSG_PEEK)

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

1 个答案:

答案 0 :(得分:1)

由于系统调用在内核空间中运行,因此它们是线程安全的(它们必须是,否则内核数据可能会被破坏并导致整个系统崩溃),因为您的程序不会崩溃 - 但是,正如所指出的那样杰里米弗里斯纳在评论中写道:

  • 可能无法保证执行系统调用的顺序。

  • 系统调用需要时间。这意味着,在您拨打recv ()

  • 之间,很多数据都会过时

但是,您肯定可以将字节写入命名FIFO。在执行read ()的线程中打开写入结束,在执行recv ()的线程中打开读取结束。

现在,每次成功完成read ()时,将第一个字节(即你想要的全部,是吗?)写入FIFO。同时,在另一个线程中,不是在sleep ()之间使用recv (),而是在FIFO上使用大小为1字节的阻塞read,并在结果中使用printf ()。 / p>

这样,只要有数据需要读取,内核就会自动唤醒recv ()线程。你不会浪费任何CPU时间和不必要的上下文切换(这实际上非常大),因此你的应用程序的整体性能/速度也会上升。