gpt4 book ai didi

c++ - 为什么 recv 在设置 SO_RCVTIMEO 时返回 -1 和 errno=EINTR?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:34:31 33 4
gpt4 key购买 nike

此问题仅在使用 SO_RCVTIMEO 设置套接字超时时发生。

recv应该阻塞 3 秒。但是一旦另一个线程启动,它就会因为 EINTR 而返回。

如果我运行线程 t2 , recv在线程中t1将返回 -1没有阻塞并设置errnoEINTR .

但是recv在线程中t1线程 t2 时正常运行没有启动,它只是阻塞 3 秒。

如果线程t2在线程 t1 之前运行, recv也能正常工作。

当我用 SlickEdit 或 gdb 调试时,我发现它每次都失败。但在终端中运行时可以正常工作。

代码如下:

test.cpp:链接-pthread使用 <thread>或者线程抛出异常

#include<unistd.h>
#include<netdb.h>
#include<string.h>
#include<thread>

int socket_fd;
sockaddr_in server_addr;

void recvThread()
{
char pData[4096];
int len = recv(socket_fd,pData,4096,0);
if(len<=0)
{
printf("len:%d\n",len);
printf("errno:%d\n",errno);
}
}

void otherThread()
{
while(1)
{
sleep(1);
}
}

int main()
{
hostent *host;
if((host=gethostbyname("127.0.0.1"))==NULL)
{
return 1;
}
memset(&server_addr, 0, sizeof(sockaddr_in));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(8887);
server_addr.sin_addr=*((in_addr*)host->h_addr);
bzero(&(server_addr.sin_zero),8);

socket_fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

timeval timeout = {3,0};
setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeval));
if(connect(socket_fd, (sockaddr*)&server_addr, sizeof(server_addr))<0)
{
return 1;
}

std::thread t1(recvThread);
std::thread t2(otherThread);
t1.join();
t2.join();
}

最佳答案

请参阅“一些程序员老兄”对 EINTR 的评论

除非可以异步设置/修改断点,否则调试器 (gdb) 需要停止目标(您的任务),设置断点,然后恢复它。要停止它,它可以发送 SIGINT,这会导致系统上的 EINTR 阻塞调用。

如果您使用 GNU C 库,您可以使用 TEMP_FAILURE_RETRY 宏,请参阅这篇文章: TEMP_FAILURE_RETRY and __USE_GNU

关于c++ - 为什么 recv 在设置 SO_RCVTIMEO 时返回 -1 和 errno=EINTR?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51666259/

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