我正在设计客户端和服务器套接字程序。 我有一个文件从客户端使用UDP传输到服务器,我重复我使用UDP ..... 我通过UDP发送,因此,发送速率比接收器快,所以我创建了3个线程监听同一个套接字,这样当一个线程正在做一些工作(我的意思是使用fwrite写入文件)时收到其他线程可以从客户端收回的数据。
我的第一个问题是,当我使用具有多个线程的fwrite时,我必须使用锁,因为文件指针在线程之间共享。我思路正确???
我的第二个问题是“如果我使用多个线程来使用锁定来使用单个线程进行fwrite工作而没有锁定,那么性能是否会有任何改进......”......请指导我...
答案 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,或实现适当的流量控制机制。