C 中的线程池内存不足,Linux
Out of memory in a thread pool in C, Linux
我需要创建无限循环并使用线程池创建例如 200 个线程来完成无限循环的工作。
我正在使用这个线程池 - https://github.com/Pithikos/C-Thread-Pool
与此同时,我正在监视服务器资源(使用 htop)并看到内存每秒增加 3 兆字节,直到内核终止应用程序。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "thpool.h"
#define MAX_IPv4 256
/* Args for thread start function */
typedef struct {
int octet1;
int octet2;
int octet3;
int octet4;
} args_struct;
/* Thread task */
void task1(void *args) {
args_struct *actual_args = args;
printf("%d.%d.%d.%d\n", actual_args->octet1, actual_args->octet2, actual_args->octet3, actual_args->octet4);
/* Do some job */
sleep(1);
/* Free the args */
free(args);
}
/* Main function */
int main( void ) {
int i=0, j=0, n=0, m=0;
/* Making threadpool n threads */
threadpool thpool = thpool_init(200);
/* Infinite loop start from the certain ip*/
while (1) {
for (i=0; i < MAX_IPv4; ++i) {
for (j=0; j < MAX_IPv4; ++j) {
for (n=0; n < MAX_IPv4; ++n) {
for (m=0; m < MAX_IPv4; ++m) {
/* Heap memory for the args different for the every thread */
args_struct *args = malloc(sizeof *args);
args->octet1 = i;
args->octet2 = j;
args->octet3 = n;
args->octet4 = m;
/* Create thread */
thpool_add_work(thpool, (void*)task1, (void*)args);
}
}
}
}
/* Start from 0.0.0.0 */
i=0;
j=0;
n=0;
m=0;
}
/* Wait until the all threads are done */
thpool_wait(thpool);
/* Destroy the threadpool */
thpool_destroy(thpool);
return 0;
}
如何解决这个问题?
查看 thpool_add_work
的代码,每次调用都会使用一些内存(分配作业记录以添加到队列中),因此当您的循环永远 运行 时,这并不奇怪它会 运行 在某些时候内存不足。您还在最内层的循环中分配内存,因此这也将有助于耗尽所有内存。
基本上在你的内部循环中,你为 args_struct
分配了 16 个字节(假设 int 为 4),并且 thpool_add_work
也分配了 12 个字节(出于对齐目的可能四舍五入为 16)。
如您所想,这对您的 4 个嵌套循环(也是 运行 无限循环)加起来很多。
正在查看您的图书馆的问题(尤其是 this one 关于内存消耗的问题)。
建议检查作业队列长度threadpool.jobqueue.len
;
也许您的代码可以在将您的作业添加到队列后进行检查
不幸的是 threadpool
是一个不透明的指针,您无法直接访问该值。
我建议在 thpool.c
中为线程池添加一个函数:
int thpool_jobqueue_length(thpool_* thpool_p) {
return thpool->jobqueue->len;
}
并且不要忘记 thpool.h
中的声明
int thpool_jobqueue_length(threadpool);
然后修改你的代码
const int SOME_ARBITRARY_VALUE = 400
...
thpool_add_work(thpool, (void*)task1, (void*)args);
while( ( thpool_jobqueue_length(thpool) > SOME_ARBITRARY_VALUE ) ) {
sleep(1);
}
...
我需要创建无限循环并使用线程池创建例如 200 个线程来完成无限循环的工作。
我正在使用这个线程池 - https://github.com/Pithikos/C-Thread-Pool
与此同时,我正在监视服务器资源(使用 htop)并看到内存每秒增加 3 兆字节,直到内核终止应用程序。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "thpool.h"
#define MAX_IPv4 256
/* Args for thread start function */
typedef struct {
int octet1;
int octet2;
int octet3;
int octet4;
} args_struct;
/* Thread task */
void task1(void *args) {
args_struct *actual_args = args;
printf("%d.%d.%d.%d\n", actual_args->octet1, actual_args->octet2, actual_args->octet3, actual_args->octet4);
/* Do some job */
sleep(1);
/* Free the args */
free(args);
}
/* Main function */
int main( void ) {
int i=0, j=0, n=0, m=0;
/* Making threadpool n threads */
threadpool thpool = thpool_init(200);
/* Infinite loop start from the certain ip*/
while (1) {
for (i=0; i < MAX_IPv4; ++i) {
for (j=0; j < MAX_IPv4; ++j) {
for (n=0; n < MAX_IPv4; ++n) {
for (m=0; m < MAX_IPv4; ++m) {
/* Heap memory for the args different for the every thread */
args_struct *args = malloc(sizeof *args);
args->octet1 = i;
args->octet2 = j;
args->octet3 = n;
args->octet4 = m;
/* Create thread */
thpool_add_work(thpool, (void*)task1, (void*)args);
}
}
}
}
/* Start from 0.0.0.0 */
i=0;
j=0;
n=0;
m=0;
}
/* Wait until the all threads are done */
thpool_wait(thpool);
/* Destroy the threadpool */
thpool_destroy(thpool);
return 0;
}
如何解决这个问题?
查看 thpool_add_work
的代码,每次调用都会使用一些内存(分配作业记录以添加到队列中),因此当您的循环永远 运行 时,这并不奇怪它会 运行 在某些时候内存不足。您还在最内层的循环中分配内存,因此这也将有助于耗尽所有内存。
基本上在你的内部循环中,你为 args_struct
分配了 16 个字节(假设 int 为 4),并且 thpool_add_work
也分配了 12 个字节(出于对齐目的可能四舍五入为 16)。
如您所想,这对您的 4 个嵌套循环(也是 运行 无限循环)加起来很多。
正在查看您的图书馆的问题(尤其是 this one 关于内存消耗的问题)。
建议检查作业队列长度threadpool.jobqueue.len
;
也许您的代码可以在将您的作业添加到队列后进行检查
不幸的是 threadpool
是一个不透明的指针,您无法直接访问该值。
我建议在 thpool.c
中为线程池添加一个函数:
int thpool_jobqueue_length(thpool_* thpool_p) {
return thpool->jobqueue->len;
}
并且不要忘记 thpool.h
int thpool_jobqueue_length(threadpool);
然后修改你的代码
const int SOME_ARBITRARY_VALUE = 400
...
thpool_add_work(thpool, (void*)task1, (void*)args);
while( ( thpool_jobqueue_length(thpool) > SOME_ARBITRARY_VALUE ) ) {
sleep(1);
}
...