我是不是需要锁定才能同时使用同一个应用程序两次写入套接字?

Posted

技术标签:

【中文标题】我是不是需要锁定才能同时使用同一个应用程序两次写入套接字?【英文标题】:Do I need locks to write into socket using the same application twice and simultaneously?我是否需要锁定才能同时使用同一个应用程序两次写入套接字? 【发布时间】:2014-12-30 01:26:10 【问题描述】:

如您所知,写入不同线程之间的共享内存需要锁(互斥锁、信号量...)。

我的 C++ 程序负责填充 SO_SNDBUF 并将数据写入套接字(作为限制网络的一部分)。

在这里你可以找到相关的代码部分:

getsockopt(sendsockfd, SOL_SOCKET, SO_SNDBUF, &sndBufferSize, &sbsLen);
...
write(sendsockfd,buffer,sndBufferSize);

当我在同一台电脑上同时运行这个程序两次(即它变成具有两个不同套接字的两个不同应用程序)时,关于写入缓冲区我能说什么,它是否被视为共享内存tcp_wmem?那么,写作应该用锁吗?

附:我正在使用阻塞模式。

【问题讨论】:

不清楚:这两个程序在做什么?他们是否共享一个套接字(在 Unix 上不太可能但可能)? “填满 SO_SNDBUF”是什么意思?我猜你的意思是你将数据从两个不同的进程发送到两个不同的套接字? 如果我的问题不清楚,请通知我,因为我昨天问了一个问题***.com/questions/27683393/…,我没有得到任何答案,也没有评论。 是什么样的socket? TCP? Unix? UDP?生的? 亲爱的@JeremyFriesner,我正在尝试填充 tcp_wmem。 @Moi:不同步地写入同一个 TCP 套接字会很糟糕,因为来自不同线程的数据最终可能会交错,让接收者没有希望再次将其整理出来。使用数据报套接字,至少来自独立线程的写入将作为单独的单元输出。幸运的是,您有单独的套接字。 【参考方案1】:

不,在这种情况下你不应该使用锁来写。想一想:如果两个不同公司编写的两个程序需要在写入独立套接字之前获得锁,它们将如何在同一台机器上工作?

即使在同一个程序中写入两个单独的套接字也不需要锁定。

【讨论】:

你是对的,我的问题是关于填充套接字的写入缓冲区。那么,如何才能在 tcp_wmem 之前都填满呢? 套接字是独立的。一个套接字的缓冲区与另一个无关。 好的,请您详细解释一下 tcp_wmem 在非常高的速率(即 wmem_max)下会发生什么? 当缓冲区填满时,发送将阻塞。也就是说,发送程序将“挂起”,直到缓冲区稍微耗尽。

以上是关于我是不是需要锁定才能同时使用同一个应用程序两次写入套接字?的主要内容,如果未能解决你的问题,请参考以下文章

使用flock的PHP问题 - 文件锁定

Mnesia:如何同时锁定多行,以便我可以写入/读取一组“一致”的记录

在同一个线程中多次锁定 CCriticalSection 是好的做法吗?

如何锁定文件并避免在写入时读取

Java中的进程间文件锁定

请写一段PHP代码,确保多个进程同时写入同一个文件成功