c - 一个线程全部退出
问题描述
我有一个生成几个线程的主程序(使用带有accept()的while循环来获取客户端),它所要做的就是“听键盘”,当用户输入单词退出时它会关闭整个程序。首先,主程序创建监听线程,然后进入接受客户端的while循环。即使侦听线程获得退出输入,循环仍然停留在接受状态。
我不必使用单独的线程来听键盘,但我找不到可行的无阻塞方式。
听力线程:
DWORD WINAPI ListenService(LPVOID lpParam)
{
char buffer[5];
if (EOF == scanf("%s", buffer))
{
printf("faile get word from keyboard\n");
}
if (buffer[4] != '\0')
strcat(buffer, "\0");
if (STRINGS_ARE_EQUAL(buffer, "exit"))
{
return 999;
}
return -1;
}
在主代码中:
ThreadListen = CreateThread(NULL,0,ListenService,NULL,0,&(ThreadId));
while(1)
{
SOCKET AcceptSocket = accept(MainSocket, NULL, NULL);
if (AcceptSocket == INVALID_SOCKET)
{
printf("Accepting connection with client failed, error %ld\n", WSAGetLastError());
CleanupWorkerThreads();
WSACleanup();
}
printf("Client Connected.\n");
}
解决方案
有许多不同的方法可以处理这个问题。
accept()
您可以通过简单地关闭侦听套接字来中止阻塞。
或者,您可以使用select()
短暂的超时来检测新客户端何时在调用之前等待accept()
。您可以在两次调用之间检查退出条件select()
。请注意,有一个小的竞争条件,客户端可能会在时间之间断开连接select()
并被accect()
调用,因此如果没有更多客户端等待,accept()
可能仍会阻塞。
或者,您可以摆脱线程,只在单个线程中使用非阻塞套接字,在套接字操作之间定期检查退出条件。
或者,您可以使用异步套接字,使用WSACreateEvent()
、WSAEventSelect()
和WSAWaitForMultipleEvents()
来检测套接字活动。然后,您可以创建一个添加事件以等待退出条件发生。
或者,您可以使用 I/O 完成端口来处理套接字活动,然后您可以将自定义退出数据包发布到 IOCP 队列中PostQueuedCompletionStatus()
,以“唤醒”任何等待线程。
推荐阅读
- android - WebView 清除锁定屏幕上的历史记录项
- .net - 如何解决看跌期权的 401 未授权错误
- javascript - 两个 random() 调用时相同的随机值?
- c# - 安装后设置没有 web.config 的 .net 5 项目
- rtmp - 带有 RTMP 协议的烤箱媒体引擎
- javascript - 如何在 vanilla JavaScript/jQuery 中有效地将 scrollTo() 与单击事件配对
- java - 如何使用 TestNg 在两个不同的类中指定 @Test 的依赖关系?
- mongodb - 如何在 mongodb 聚合中的 $sum 中使用 $match?
- python - 启用 OAuth 身份验证时出现 Apache Superset TypeError
- linux - 解析从 whois 收到的数据