У меня есть простая программа на C, которая должна прослушивать подключения и запускать новый поток для каждого подключаемого клиента. Поток просто печатает, какие сообщения он получает (пока). При этом я следил за двумя учебными пособиями.Простой приемник Socket и потоки памяти Утечка
Работает, но я попытался подключиться и отключиться повторно с netcat без отправки каких-либо сообщений. Каждый раз, когда я подключаюсь, программа занимает 8 КБ памяти, но при отключении она освобождает только 4 КБ. Но я не могу найти причину утечки. Он завершает поток и закрывает сокет каждый раз, когда пользователь отключается. Вот весь код вовлеченный:
void* clientFunction(void* arg) {
char receiveBuffer[RECEIVE_BUFFER_SIZE];
long receiveSize;
int clntSocket = * ((int*) arg);
while (true) {
//receive messages
receiveSize = recv(clntSocket, receiveBuffer, RECEIVE_BUFFER_SIZE, 0);
if (receiveSize <= 0) {
close(clntSocket);
return NULL;
}
printf("Received message: %s", receiveBuffer);
memset(&receiveBuffer, 0, sizeof(receiveBuffer));
}
return 0;
}
int main(int argc, const char * argv[]) {
//FOR LISTENING SOCKET =====
int servSock; /* Socket descriptor for server */
int clntSock; /* Socket descriptor for client */
struct sockaddr_in serverAddress; /* Local address */
struct sockaddr_in clientAddress; /* Client address */
unsigned int clntLen; /* Length of client address data structure */
// =======
/* Create socket for incoming connections */
if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
printf("Socket creation failed!\n");
return SOCKET_ERROR;
}
memset(&serverAddress, 0, sizeof(serverAddress)); /* Zero out structure */
serverAddress.sin_family = AF_INET; /* Internet address family */
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
serverAddress.sin_port = htons(PORT); /* Local port */
if (bind(servSock, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) {
printf("Socket binding failed!\n");
return SOCKET_ERROR;
}
if (listen(servSock, MAXPENDING) < 0) {
printf("Socket listening failed!\n");
return SOCKET_ERROR;
}
isListening = true;
int* arg = &clntSock;
while (isListening) { //should have a timer?
/* Set the size of the in-out parameter */
clntLen = sizeof(clientAddress);
/* Wait for a client to connect */
if ((clntSock = accept(servSock, (struct sockaddr *) &clientAddress, &clntLen)) >= 0) { //??????
/* clntSock is connected to a client! */
pthread_t clientThread;
pthread_create(&clientThread, NULL, &clientFunction, (void*) arg);
}
}
return 0;
}
Похоже, вам может потребоваться звонок pthread_detach. –
Как вы оцениваете, что есть утечка? Возможно, что какая-то базовая система (пока) не отказывается от какой-то памяти, которую она может повторно использовать позже. Вы можете видеть, как это происходит на простой 'malloc', за которой следует' free'. Лучшим тестом было бы запустить программу на некоторое время и посмотреть, если вы получите линейное увеличение использования памяти при выполнении N соединений в минуту. – mvds
Хорошо, я попробую долгосрочный тест. Я не знал, что так оно и будет. – sudo