Эта проблема возникает только тогда, когда для сокета установлено время ожидания с помощью SO_RCVTIMEO.
recv
должен заблокироваться на 3 секунды. Но он возвращается из-за EINTR, как только запускается другой поток.
Если я запускаю поток t2
, recv
в потоке t1
вернет -1
без блокировки и установит errno
в EINTR
.
Но 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
означает? Пожалуйста, начните с чтения страницы руководстваrecv
. - person Some programmer dude   schedule 03.08.2018