我开发了一个单服务器/多客户端 TCP 应用程序。
客户端由 x 个线程组成,每个线程处理自己的数据,然后通过 TCP 套接字将数据发送到服务器进行显示。
服务器基本上是一个带有窗口的图形用户界面。服务器从客户端接收数据并显示。
现在的问题是,由于客户端内部有 40 个线程,每个线程都想发送数据,我如何使用一个连接的套接字来实现这一点?
我的建议:
我的方法是在 40 个线程中的每一个线程中创建一个数据结构,其中将维护要发送的数据。然后创建一个单独的发送线程,在客户端有一个连接的套接字。该线程将从第一个线程的数据结构中读取数据,通过套接字发送数据,然后从第二个线程读取数据,依此类推。
困惑:
但我不确定这将如何实现,因为我是新手? :( 如果线程正在写入数据结构并且发送线程尝试同时读取数据怎么办。我熟悉互斥锁、临界区等,但对于我的简单应用程序来说这听起来太复杂了。
除我自己的建议外,欢迎提出任何其他建议/意见。 如果您认为我自己的做法是正确的,那么请帮助我解决我上面提到的困惑。
提前致谢:)
编辑:
我能否将定时器放在发送线程上,并在特定时间后发送线程暂停线程#1(以便它可以访问其数据结构而不会出现任何同步问题),从其数据结构中读取数据,通过 tcp 发送数据套接字,并恢复线程#1,然后暂停线程#2,从其数据结构中读取数据,通过 tcp 套接字发送数据,然后恢复线程#2,依此类推。
最佳答案
一种常见的方法是让一个线程专用于发送数据。其他线程将它们的数据发布到共享容器(列表、双端队列等)中,并向发送方线程发出数据可用的信号。然后发送方醒来并处理任何可用数据。
编辑:
主要内容如下:
HANDLE data_available_event; // manual reset event; set when queue has data, clear when queue is empty
CRITICAL_SECTION cs; // protect access to data queue
std::deque<std::string> data_to_send;
WorkerThread()
{
while(do_work)
{
std::string data = generate_data()
EnterCriticalSection(&cs);
data_to_send.push_back(data);
SetEvent(data_available_event); // signal sender thread that data is available
LeaveCriticalSection(&cs);
}
}
SenderThread()
{
while(do_work)
{
WaitForSingleObject(data_available_event);
EnterCriticalSection(&cs);
std::string data = data_to_send.front();
data_to_send.pop_front();
if(data_to_send.empty())
{
ResetEvent(data_available_event); // queue is empty; reset event and wait until more data is available
}
LeaveCriticalSection(&cs);
send_data(data);
}
}
当然,这是假设数据可以按任何顺序发送。我仅出于说明目的使用字符串;您可能需要某种知道如何序列化它所持有的数据的自定义对象。
关于c - x 向服务器发送数据以在 GUI 上显示输出的线程数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16834732/