Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当设置为-1时,为什么recv返回-1且errno=EINTR?_C++_Linux_Recv_Setsockopt - Fatal编程技术网

C++ 当设置为-1时,为什么recv返回-1且errno=EINTR?

C++ 当设置为-1时,为什么recv返回-1且errno=EINTR?,c++,linux,recv,setsockopt,C++,Linux,Recv,Setsockopt,此问题仅在使用SO_RCVTIMEO设置套接字超时时出现 recv应阻止3秒。但它会在另一个线程启动时返回,因为EINTR 如果我运行线程t2,线程t1中的recv将返回-1而不阻塞,并将errno设置为EINTR 但是线程t1中的recv功能正常,当线程t2未启动时,它只会阻塞3秒钟 如果线程t2在线程t1之前运行,recv也能正常工作 我发现每次使用SlickEdit或gdb进行调试时,它都会失败。但在终端运行时工作正常 以下是代码: test.cpp:链接-pthread使用或线程抛出异常

此问题仅在使用SO_RCVTIMEO设置套接字超时时出现

recv
应阻止3秒。但它会在另一个线程启动时返回,因为EINTR

如果我运行线程
t2
,线程
t1
中的
recv
将返回
-1
而不阻塞,并将
errno
设置为
EINTR

但是线程
t1
中的
recv
功能正常,当线程
t2
未启动时,它只会阻塞3秒钟

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


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

以下是代码:

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

#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();
}
#包括
#包括
#包括
#包括
int-socket_-fd;
服务器地址中的sockaddr\u;
void recvThread()
{
char-pData[4096];
int len=recv(插座fd,pData,4096,0);
if(lenh_addr);
bzero(&(服务器地址sin_zero),8);
socket\u fd=socket(PF\u INET、SOCK\u STREAM、IPPROTO\u TCP);
timeval timeout={3,0};
setsockopt(socket_fd、SOL_socket、SO_RCVTIMEO和timeout、sizeof(timeval));

如果(connect(socket\u fd,(sockaddr*)和server\u addr,sizeof(server\u addr))这是一个潜在的错误

bzero(&(server_addr.sin_zero),8);
应该是

bzero(&(server_addr.sin_zero), sizeof(server_addr.sin_zero));
添加信号处理程序以找出错误是什么,因为有一种方法可以处理所有错误。

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

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

如果您使用GNU C库,您可以使用TEMP\u FAILURE\u RETRY宏,请参阅本文:

你知道EINTR
的意思吗?请从阅读开始。我不知道它为什么会被信号中断?std::thread t2(otherThread)调用将发送一个信号?如果你的第二个线程没有执行问题中所示的任何操作,这将不会导致向进程发送信号(但会导致浪费大量CPU周期)。它可以是任何信号,如果没有合适的命令,我们根本无法了解更多。我更新了那里的所有代码。因为我无法从内部机器复制,所以可能会有一些键入错误。此代码可以显示我的要求。奇怪的部分是:通过交换std:thread t1 t2的调用顺序,recv可以正常工作。
bze在上一次
memset
调用之后,甚至不需要ro
调用。我删除了bzero,但没有任何更改。我尝试了一些方法使其工作。甚至睡眠(1)在std::thread t1和recv block 1sec之后,然后recv在t2启动时返回-1。我发现每次使用SlickEdit或gdb进行调试时它都会失败。但当它在终端中运行时会正常工作。