This problem only hapens when socket is set timeout with SO_RCVTIMEO.
recv
should block for 3sec. But it returns because of EINTR as soon as another thread starts.
If I run thread t2
, recv
in thread t1
will return -1
without blocking and sets errno
to EINTR
.
But recv
in thread t1
functions normally when thread t2
is not started, it just blocks for 3 seconds.
If thread t2
runs before thread t1
, recv
also works properly.
I found it fails every time when I was debuging with SlickEdit or gdb. But works properly when it runs in terminal.
Here is code:
test.cpp: link -pthread
to use <thread>
or thread throws exception
#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();
}