2016-12-28 182 views
1

我创建了一个TCP客户端应用程序,并决定使用c中的pthread库使用新线程处理传入数据。多线程写入套接字

但是,我在某处发现,当多个线程尝试写入同一个套接字连接的文件描述符时,可能会发生意想不到的事情。

什么是确保这些“意想不到的事情”不会发生的最佳方法。

是否还需要首先使用线程?

注意:我决定使用线程是为了防止任何阻塞操作。

+1

最好的方法是确保只有一个线程读取/写入套接字。注意:在决定使用线程之前,你需要解释为什么阻塞是不可取的。 – user3386109

+0

投票关闭:太宽 – Stargateur

+0

该应用程序是USSD应用程序 - 非结构化补充服务数据。它将服务多个用户,有时几乎在同一时间拨打短代码。 USSD网关有效超时,并且要求客户端应用程序在此时间范围内提供响应。当用户需要等待时,他们的请求可能会超时,用户体验将受到严重影响。 –

回答

1

为避免阻塞,您应该研究异步操作。您可以了解您的特定平台如何处理它们,或者使用库(如ASIO(https://think-async.com/))来处理它。

-2
  • 是的,你需要创建线程,如果你想要做什么都在等待进入的TCP数据

  • 是的,你需要照顾的,可能在多线程程序中发生意想不到的事情

您应该使用Mutexes来防止所谓的意外事件。您用于创建线程的pthread库也包含同步基元。

的样本程序可能看起来像这样

pthread_mutex_t tcp_lock; 

void ThreadFunction() 
{ 
     pthread_mutex_lock(&tcp_lock); 
     // Do your stuffs 
     pthread_mutex_unlock(&tcp_lock); 
} 

int MainThread() 
{ 
    pthread_mutex_lock(&tcp_lock); 
    // Do your stuffs 
    pthread_mutex_unlock(&tcp_lock); 
} 
+2

“是的,如果您想在等待传入的TCP数据时执行其他任何操作,则需要创建线程”,否。男人选择,民意调查。他们有很多方法来做服务器,线程就是其中之一。 – Stargateur

+0

不,如果您在等待传入的TCP数据时想做其他任何事情,则不需要创建线程。您可以使用非阻塞或多路复用或异步I/O。 – EJP

0

我可能会建议使用libuv?它高度维护(node.js的核心)和跨平台。

此外,你不应该使用select()这是旧学校。如果你自己做了,你应该在Linux上使用epoll()。它规模更好。

你应该只有一个作家线程。该线程应该在套接字不忙时写入。

结帐libuv - 它为你处理所有这些混乱,但仍然让你接近金属。 https://nikhilm.github.io/uvbook/networking.html

我对这类东西的处理方式通常是有一个写入程序线程和一个快速读取程序回调,通常只是为传入数据分配内存,然后将其分配给一个或多个处理线程。如果你想快速避免memcpy不惜一切代价,并分配一个大缓冲区开始。