【发布时间】:2016-10-01 23:11:50
【问题描述】:
在 PTHREADS 方面需要一些帮助。我想随时保持打开 1000 多个线程,就像线程池一样。这是代码:
/*
gcc -o test2 test2.cpp -static -lpthread -lstdc++
*/
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstring>
#include <stdexcept>
#include <cstdlib>
int NUM_THREADS = 2000;
int MAX_THREADS = 100;
int THREADSTACK = 65536;
struct thread_struct{
int arg1;
int arg2;
};
pthread_mutex_t mutex_;
static unsigned int thread_count = 0;
string exec(const char* cmd)
{
int DEBUG=0;
char buffer[5000];
string result = "";
FILE* pipe = popen(cmd, "r");
if (!pipe && DEBUG) throw runtime_error("popen() failed!");
try
{
while (!feof(pipe))
{
if (fgets(buffer, 128, pipe) != NULL)
{
result += buffer;
}
}
}
catch(...)
{
pclose(pipe);
throw;
}
pclose(pipe);
return result;
}
void *thread_test(void *arguments)
{
pthread_mutex_lock(&mutex_);
thread_count++;
pthread_mutex_unlock(&mutex_);
// long tid;
// tid = (long)threadid;
struct thread_struct *args = (thread_struct*)arguments;
/*
printf("ARG1=%d\n",args->arg1);
printf("ARG2=%d\n",args->arg2);
*/
int thread_id = (int) args->arg1;
/*
int random_sleep;
random_sleep = rand() % 10 + 1;
printf ("RAND=[%d]\n", random_sleep);
sleep(random_sleep);
*/
int random_sleep;
random_sleep = rand() % 10 + 5;
// printf ("RAND=[%d]\n", random_sleep);
char command[100];
memset(command,0,sizeof(command));
sprintf(command,"sleep %d",random_sleep);
exec(command);
random_sleep = rand() % 100000 + 500000;
usleep(random_sleep);
// simulation of a work between 5 and 10 seconds
// sleep(random_sleep);
// printf("#%d -> sleep=%d total_threads=%u\n",thread_id,random_sleep,thread_count);
pthread_mutex_lock(&mutex_);
thread_count--;
pthread_mutex_unlock(&mutex_);
pthread_exit(NULL);
}
int main()
{
// pthread_t threads[NUM_THREADS];
int rc;
int i;
usleep(10000);
srand ((unsigned)time(NULL));
unsigned int thread_count_now = 0;
pthread_attr_t attrs;
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, THREADSTACK);
pthread_mutex_init(&mutex_, NULL);
for( i=0; i < NUM_THREADS; i++ )
{
create_thread:
pthread_mutex_lock(&mutex_);
thread_count_now = thread_count;
pthread_mutex_unlock(&mutex_);
// printf("thread_count in for = [%d]\n",thread_count_now);
if(thread_count_now < MAX_THREADS)
{
printf("CREATE thread [%d]\n",i);
struct thread_struct struct1;
struct1.arg1 = i;
struct1.arg2 = 999;
pthread_t temp_thread;
rc = pthread_create(&temp_thread, NULL, &thread_test, (void *)&struct1);
if (rc)
{
printf("Unable to create thread %d\n",rc);
sleep(1);
pthread_detach(temp_thread);
goto create_thread;
}
}
else
{
printf("Thread POOL full %d of %d\n",thread_count_now,MAX_THREADS);
sleep(1);
goto create_thread;
}
}
pthread_attr_destroy(&attrs);
pthread_mutex_destroy(&mutex_);
// pthread_attr_destroy(&attrs);
printf("Proccess completed!\n");
pthread_exit(NULL);
return 1;
}
在产生 300 个线程后,它开始提供
错误,pthread_create() 的返回码是 11,然后继续一一执行。
我做错了什么?
【问题讨论】:
-
一般来说,产生数百个线程是个坏主意,因为线程性能往往不能很好地扩展。您可能需要重新考虑程序的设计,以支持使用数十个而不是数百个线程。理想情况下,程序中的线程数应等于机器上的内核数。
-
你为什么这么说?我有使用
fork()运行的程序,它对我有很大帮助,我什至一直在 1500 个分叉上表现出色 -
用更少的线程可以更有效地工作。每个线程都必须为其自己的单独堆栈分配空间,这会耗尽内存。此外,每次 CPU 必须从一个线程切换到另一个线程时,都需要进行上下文切换,这会占用 CPU 周期。最后,如果您使用进程而不是线程(正如您提到使用 fork() 而不是 pthread_create() 所暗示的那样),那么每个进程还需要自己的进程空间,这会占用大量额外的内存。您可以使用大量线程/进程(无论如何,直到您达到系统的限制)但效率低下。
标签: c++ multithreading