多个线程有锁与单线程?

时间:2011-09-25 20:37:01

标签: c++ sockets mutex

我正在设计客户端和服务器套接字程序。 我有一个文件从客户端使用UDP传输到服务器,我重复我使用UDP ..... 我通过UDP发送,因此,发送速率比接收器快,所以我创建了3个线程监听同一个套接字,这样当一个线程正在做一些工作(我的意思是使用fwrite写入文件)时收到其他线程可以从客户端收回的数据。

我的第一个问题是,当我使用具有多个线程的fwrite时,我必须使用锁,因为文件指针在线程之间共享。我思路正确???

我的第二个问题是“如果我使用多个线程来使用锁定来使用单个线程进行fwrite工作而没有锁定,那么性能是否会有任何改进......”......请指导我...

5 个答案:

答案 0 :(得分:2)

在写入之前缓存数据。 让写作发生在另一个线程中。

按照您的方式进行操作需要锁定插座。

Q1:是的,你确实需要锁定它(非常慢!)。为什么不在每个线程中使用单独的文件描述符?问题主要来自该描述符管理的当前文件位置。

Q2:两者都没有。如果数据需要排序(是的,UDP!),你仍然应该缓冲它。 RAM比磁盘IO快得多。提供一个流来缓冲它并在一个单独的线程中处理该流中的数据。

答案 1 :(得分:2)

我会使用一个帖子。挽救并发症。您可以缓冲数据并使用异步写入

http://www.gnu.org/s/hello/manual/libc/Asynchronous-Reads_002fWrites.html

答案 2 :(得分:1)

  

我的第一个问题是当我使用带有多个线程的fwrite时,我必须使用锁,因为文件指针在线程之间共享

是的,当多个线程写入单个对象(文件,内存等)时,您总是必须使用锁。

  

我的第二个问题是“如果我使用多个线程使用锁定来使用单个线程来执行fwrite工作而没有锁定,那么性能是否会有任何改进......”

我会使用两个线程。第一个线程什么都不做,只读取套接字并将数据存储在内存中。第二个线程从内存中读取数据并将其写入文件。将内存缓冲区视为FIFO队列,并使用互斥锁来保护队列指针。你将从第三个线程中获得任何收益。事实上,它可能会损害性能,这肯定会使问题变得更加复杂。

答案 3 :(得分:1)

Ed's answer类似,我建议为您的服务器使用异步I / O和单个线程。虽然我觉得使用Boost.Asio比使用posix AIO更容易。

答案 4 :(得分:1)

首先,尽量避免使用UDP进行批量传输。如果使用UDP,则必须重新创建自己的流控制协议,以及重传和重新排序的逻辑。从它的声音,你的问题归结为缺少流量控制 - 所以为什么不只是使用TCP?

无论如何,不​​要把你的文件写在另一个线程中。在任何情况下,现代操作系统都会在内部缓冲磁盘写入 - 如果您写入数据的速度比磁盘可以跟上的速度快得多,那么您只会开始阻塞,在这种情况下,在进程内部缓冲最多只需要几秒钟。切换到TCP,或实现适当的流量控制机制。