Winsock多客户端和多线程,计算机努力工作
Winsock multi clients and multi thread, Computer works hard
我正在尝试在C 插座编程中构建多客户端服务器,并且在多线程中发现了一些麻烦。我使用_beginthread创建一些线程。当我们想构建多样服务器时,我认为我们应该有一个线程,可以随时处理套接字ACCEPTER,到目前为止,它可以正常工作(对我来说没问题)。
之后,我制作了一些线程来处理 client-datareceiver ,我认为它比我们创建1个线程更好地处理所有客户端。我认为,多线程会更好,因为它们同步工作。
当我完成所有操作时,服务器工作得如此缓慢/硬,甚至可以使用100%CPU使用?也许我的代码上有一些缺少/错误?
void Initialize(){
[....Server initialize goes here...]
_beginthread( acceptNewClient, 0, (void*)1); //the thread that handle accepter
}
SOCKET ClientSocket;
void acceptNewClient(void* arg)
{
while(true){
ClientSocket = accept(ListenSocket,NULL,NULL);
if (ClientSocket != INVALID_SOCKET)
{
char value = 1;
setsockopt( ClientSocket, IPPROTO_TCP, TCP_NODELAY, &value, sizeof( value ) );
Client_Socket *client = new Client_Socket(ClientSocket);
_beginthread(ReceiveFromClient, 1,client ); //handle of client data receiver
client_list.push_back(client);
}
}
}
void ReceiveFromClient(void* client_sockets)
{
Client_Socket * client_socket = (Client_Socket*)client_sockets;
while(true){
server->doReceive();
}
}
编辑:
弄清楚这种情况后,我认为CAUSER是线程本身我什至尝试了新的控制台项目:
#include <process.h>
void tes(void * arg){
while(true){
}
}
int _tmain(int argc, _TCHAR* argv[])
{
_beginthread( tes, 0, (void*)1);
_beginthread( tes, 0, (void*)1);
_beginthread( tes, 0, (void*)1);
_beginthread( tes, 0, (void*)1);
_beginthread( tes, 0, (void*)1);
_beginthread( tes, 0, (void*)1);
_beginthread( tes, 0, (void*)1);
_beginthread( tes, 0, (void*)1);
_beginthread( tes, 0, (void*)1);
_beginthread( tes, 0, (void*)1);
_beginthread( tes, 0, (void*)1);
_beginthread( tes, 0, (void*)1);
while(true){}
return 0;
}
线程对于计算机来说太难了,我认为错误是线程本身。这些代码确实使CPU 100%CPU,我的线程代码或解决方案解决此情况有问题吗?
正如我在几个小时前暗示的那样,原因是由于某种原因,您已将插座放入非阻滞模式,而您不使用select(),只需旋转围绕RECV()循环。无论如何,这都是没有意义的,因为您每次连接都使用线程。
根据您的答案,该解决方案不是将套接字放回阻塞模式,而是要删除 emove 首先设置非阻止模式的代码,阻止模式为默认模式,如@chao所指出的。
100%CPU很可能是由循环引起的(while(true) server->doReceive();
)。使用套接字的正确方法是在插座上等待,直到对其进行有用的操作。标准C 函数可以启用这是select
。
更高级的方法是使用I/O完成端口,但是在您的阶段,技术太先进了,甚至可能不需要。
我发现了问题。首先,如果您想使用每个客户端构建服务器,那么第一件事必须知道的是:
确保已使用ioctlsocket事先将插座设置为阻塞模式
这实际上是非常有意义的!好吧,当我们创建这样的线程时:
unsigned __stdcall threadFunc(void * arg)
{
while(1) {
}
return 0;
}
看起来很简单的线程代码,但是导致CPU的工作非常努力。当recv winsocks的函数以非阻止模式调用时,当没有更长的数据读取数据时,它们将始终重复对while表示,它们会像comp一样快速地旋转。当然,这不是好主意。因此,如果我们想克服它,当然正确的方法是:将插座设置为非块。
u_long iMode = 0;
iResult = ioctlsocket(ClientSocket, FIONBIO, &iMode);
当recv()插座时,调用机器将等到他们有一些字节要读取。以这种方式"快速旋转"将不再发生
反正谢谢..
- 努力将整数转换为链表。不知道我在这里做错了什么
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- EvtExportLogneneneba API正在将远程计算机的事件日志保存到远程PC本身.如何将其保存到主机
- 为什么我能够为阵列分配比计算机实际拥有的内存更多的内存
- 我可以使用任何好的逻辑来阻止计算机将 O 放在井字游戏中的现有 X 上
- C++ 计算机猜测用户数量在 7 次猜测以内
- C++为什么我的编译器成功了,但我的计算机给出了调试错误?
- ConstexPR :GCC比Clang更努力地评估ConstexPR
- 在 c++ 中连接字符串和整数,以便在 C++ 11 不支持计算机的情况下读取多个文件
- 我的 SDL2 程序需要哪些二进制文件,以便它在另一台未安装 SDL2 的计算机中工作
- 将非常大的 int 转换为双倍,在某些计算机上会损失精度
- 如何在个人计算机和群集 (c++) 上生成相同的随机数
- 系统错误:程序无法启动,因为您的计算机中缺少MSVCP140D.DLL。尝试重新安装该程序以解决此问题
- 我在解决此错误时遇到问题.我正在努力在主函数中传递数组
- 预处理的 C/C++ 文件是否特定于计算机?
- Windows桌面程序保存您的计算机会话 - 基于程序崩溃时的恢复会话
- 我会导致太多内存泄漏,以至于我的计算机无响应吗?
- 在多 GPU 计算机中查找空闲 GPU
- 我该如何编码,使计算机知道两个名称条目和三个名称条目之间的区别
- Winsock多客户端和多线程,计算机努力工作