简体   繁体   English

posix C write()和线程安全

[英]The posix C write() and thread-safety

There is a way to serialize the C write() so that I can write bytes on a socket, shared between k-threads, with no data-loss? 有一种方法可以序列化C write()这样我就可以在套接字上写入字节,在k线程之间共享,没有数据丢失? I imagine that a solution to this problem includes user-space locking, and what about scalability? 我想这个问题的解决方案包括用户空间锁定,以及可扩展性如何? Thank you in advance. 先感谢您。

I think the right answer depends on whether your threads need to synchronously wait for a response or not. 我认为正确的答案取决于您的线程是否需要同步等待响应。 If they just need to write some message to a socket and not wait for the peer to respond, I think the best answer is to have a single thread that is dedicated to writing messages from a queue that the other threads place messages on. 如果他们只需要向套接字写一些消息而不是等待对等体做出响应,我认为最好的答案是让一个专用于从其他线程发送消息的队列中写入消息的线程。 That way, the worker threads can simply place their messages on the queue and get on with doing something else. 这样,工作线程可以简单地将他们的消息放在队列中,然后继续做其他事情。

Of course, the queue has to be protected by a mutex but any one thread only has to hold the lock for as long as it is manipulating the queue (guaranteed to be quite a short time). 当然,队列必须受互斥锁保护,但任何一个线程只需要在操作队列时保持锁定(保证很短的时间)。 The more obvious alternative of letting every thread write directly to the socket requires each thread to hold the lock for as long as it takes the write operation to complete. 让每个线程直接写入套接字的更明显的替代方案是每个线程都要保持锁定,只要它完成写操作。 This will always be much longer than just adding an item to a queue since write is a system call and potentially, it could block for a long period. 这总是比仅仅将一个项目添加到队列要长得多,因为写入是一个系统调用,并且可能会长时间阻塞。

Even if your threads need a response to their messages, it may still pay to do something similar. 即使你的线程需要对他们的消息做出响应,它仍然可能需要做类似的事情。 Your socket servicing thread becomes more complex because you'll have to do something like select() on the socket for reads and writes to stop it from blocking and you'll also need a way to match up messages to responses and a way to inform the threads when their responses have arrived. 您的套接字服务线程变得更加复杂,因为您必须在套接字上执行类似select()的操作以进行读取和写入以阻止阻塞,并且还需要一种方法来将消息与响应进行匹配以及通知方式他们的回复到达时的线程。

Since POSIX does not seem to specify atomicity guarantees on send(2), you will likely have to use a mutex. 由于POSIX似乎没有在send(2)上指定原子性保证,因此您可能必须使用互斥锁。 Scalability of course goes down the drain with this sort of serialization. 当然,这种序列化可以降低可扩展性。

One possible approach would be to use the locking mechanism. 一种可能的方法是使用锁定机构。 Every thread should wait for a lock before writing any thing on the socket and should release the lock, once it is done. 每个线程都应该等待锁定,然后才能在套接字上写入任何内容,并且一旦完成就应该释放锁定。 If all of your threads are sending exactly the same kind of messages, the receiver end would not have any problem in reading the data, but if different threads can send different kind of data with possible different info, you should have an unique message id associated with each kind of data and its better to send the thread id as well (although not necessary, but might help you in debugging small issues). 如果所有线程都发送完全相同类型的消息,接收方端在读取数据时不会有任何问题,但如果不同的线程可以发送具有不同信息的不同类型的数据,则应该有一个唯一的消息ID关联使用每种数据并最好发送线程ID(虽然没有必要,但可能会帮助您调试小问题)。

You can have a structure like: 你可以有一个像这样的结构:

typedef struct my_socket_data_st
{
int msg_id;
#ifdef __debug_build__
    int thread_id;
#endif
size_t data_size_in_bytes;
.... Followed by your data ....
} my_socket_data_t

Scalability depends on a lot things including the hardware resources on which your application would be running. 可伸缩性取决于很多东西,包括运行应用程序的硬件资源。 Since it is a network application, you will have to think about the network bandwidth as well. 由于它是网络应用程序,因此您还必须考虑网络带宽。 Although there is no (there are a few, but I think you can ignore them for now for your application) limitation from OS on sending/receiving data over a socket, but you will have to consider about making the send synchronous or asynchronous based on your requirement. 虽然没有(有一些,但我认为你现在可以忽略它们用于你的应用程序)操作系统通过套接字发送/接收数据的限制,但你必须考虑使send同步或异步基于你的要求。 Also since, you are taking a lock, you will have to think about lock congestion as well. 此外,由于您正在锁定,您还必须考虑锁定拥塞。 If the lock is not available easily for other threads, that will degrade the performance by a huge factor. 如果其他线程无法轻松获得锁定,则会导致性能下降。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM