У меня реализовать сокет связи, как следующее:вопрос производительности RECV в C
Гнездо Клиент посылает «0010ABCDEFGHIJ» на сервер сокета, первые 4 байта (в данном случае, «0010») описывают тело сообщения имеет 10 байтов, и последующие байты - это тело сообщения !!
Я использую «The Linux Programming Interface» readn функции в стороне сервера, источник:
ssize_t
readnx(int fd, void *buffer, size_t n)
{
ssize_t numRead; /* # of bytes fetched by last read() */
size_t totRead; /* Total # of bytes read so far */
char *buf;
buf = (char*) buffer; /* No pointer arithmetic on "void *" */
for (totRead = 0; totRead < n;) {
numRead = recv(fd, buf, n - totRead,MSG_NOSIGNAL);
if (numRead == 0) /* EOF */
return totRead; /* May be 0 if this is first read() */
if (numRead == -1) {
if (errno == EINTR)
continue; /* Interrupted --> restart read() */
else
return -1; /* Some other error */
}
totRead += numRead;
buf += numRead;
}
return totRead; /* Must be 'n' bytes if we get here */
}
void *thread1(void *param)
{
int nread = 0 ;
char strdata[1024]={0},strtmp[128]={0} ;
pthread_detach(pthread_self());
while(1)
{
memset(strtmp,0x00,sizeof(strtmp)) ;
if ((nread = readnx(sd,strtmp,4)) <= 0){
break ;
}
int ilen = atoi(strtmp) ;
memset(strdata,0x00,sizeof(strdata)) ;
if ((nread = readnx(sd,strdata,ilen)) <= 0){
break ;
}
}//while
}
Это прекрасно работает для меня, я хотел бы узнать более подробную информацию о производительности, У меня есть функция 2 readnx вызовы в моем исходном коде и выполнение этого в режиме блокировки. Если я изменил свой код, чтобы сначала сделать recv с MSG_PEEK, после того, как все 14 байтов будут доступны, затем вызовите readnx один раз, чтобы получить все данные, Будет ли это быстрее, чем мои оригинальные 2 вызова readnx?!
мне интересно, в моем оригинальном источнике, у меня есть 2 readnx к ПРИЕМУ «0010» и «ABCDEFGHIJ» отдельно, будет ли это причина ядра Linux для копирования пользовательского пространства в два раза даже все 14 байт, все там уже на время I называется первым readnx?! Или ядро копирует все 14 байтов в пространство пользователя только один раз, функция readnx просто считывает его из пользовательского пространства?!
Если мне нравится знать эти сведения о процедурах пространства ядра для пользователя, какие документы, вызов функции могут помочь мне просмотреть детали.
удалить C++ tag now .. исправить ошибку. – barfatchen
Btw, так как вы заинтересованы в сокращении накладных расходов, вы можете избавиться от этих вызовов memset(), поскольку recv() будет немедленно перезаписывать эти же байты в любом случае. Нет смысла переписывать их дважды. (Вам нужно будет написать один байт NUL-терминатора в позиции nread'th, чтобы строка NUL была завершена, так что atoi() будет работать правильно) –
Количество вызовов recv() на сообщение может быть уменьшено до 1 (или меньше), всегда считывая как можно больше байтов для каждого вызова (в большой массив), а затем анализируя как можно больше байтов из этого массива и сохраняя остальное на потом.Недостатком является то, что логика состояния, необходимая для этого, довольно сложна и сложна, чтобы получить право во всех случаях, и я был бы удивлен, если бы вы видели какую-либо измеримую разницу в производительности, если только ваш входящий поток данных (например, сотни мегабайт в секунду), или ваш процессор работает очень медленно. –