gpt4 book ai didi

c++ - 停止阻塞在 recv() 上的接收器线程

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:05:08 25 4
gpt4 key购买 nike

我有一个聊天应用程序,它有一个单独的线程来监听传入的消息。

while (main thread not calling for receiver to quit) {
string message = tcpCon.tcpReceive(); // Relies on the recv() function
processIncomingMessage(message);
}

这种工作方式有一个大问题。大多数时候,循环将阻塞在 recv() 上,因此接收线程不会退出。在几秒钟后不强制线程终止的情况下,解决此问题的正确方法是什么?

最佳答案

使用 shutdown() 关闭套接字,为所有接收器关闭它。

这会在我的系统上打印出“recv returned 0”,表明接收器正常关闭。注释掉 shutdown() 并观察它永远挂起。

从长远来看,OP 应该修复设计,使用 select 或在协议(protocol)中包含明确的退出消息。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>

/* Free on my system. YMMV */
int port = 7777;
int cd;

void *f(void *arg)
{
/* Hack: proper code would synchronize here */
sleep(1);

/* This works: */
shutdown(cd, SHUT_RDWR);

close(cd);
return 0;
}

int main(void)
{
/* Create a fake server which sends nothing */
int sd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sa = { 0 };
const int on = 1;
char buf;
pthread_t thread;
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_ANY);
sa.sin_port = htons(port);
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on);

/* Other error reporting omitted for clarity */
if (bind(sd, (const struct sockaddr*)&sa, sizeof sa) < 0) {
perror("bind");
return EXIT_FAILURE;
}

/* Create a client */
listen(sd, 1);
cd = socket(AF_INET, SOCK_STREAM, 0);
connect(cd, (const struct sockaddr*)&sa, sizeof sa);
accept(sd, 0, 0);

/* Try to close socket on another thread */
pthread_create(&thread, 0, f, 0);
printf("recv returned %d\n", recv(cd, &buf, 1, 0));
pthread_join(thread, 0);

return 0;
}

关于c++ - 停止阻塞在 recv() 上的接收器线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8049677/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com