【问题标题】:Pthreads pool, keeping 1000 opened threads, pthread_create() returns 11pthreads池,保持1000个打开的线程,pthread_create()返回11
【发布时间】: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


【解决方案1】:

根据website,错误码11对应EAGAIN,表示根据this

  • 资源不足,无法创建另一个线程。
  • 遇到了系统对线程数施加的限制。

因此,要解决您的问题,要么创建更少的线程,要么在创建新线程之前等待正在运行的线程完成。

您还可以更改默认线程堆栈大小,请参阅pthread_attr_setstacksize

【讨论】:

  • 感谢您的回答。如果你仔细看,我实际上使用了pthread_attr_setstacksize(&amp;attrs, THREADSTACK);,它使用正确吗?
  • 可以,只要您不在PTHREAD_STACK_MIN (16384) 下方添加THREADSTACK_SIZE
  • 应该`pthread_attr_t attrs; pthread_attr_init(&attrs); pthread_attr_setstacksize(&attrs, THREADSTACK); pthread_mutex_init(&mutex_, NULL);` 在for( i=0; i &lt; NUM_THREADS; i++ ) 循环内?还是在外面可以吗?
  • 可以把它放在循环之外,但是你应该在你的pthread_create函数中链接pthread_attr_t,即pthread_create(&amp;temp_thread, &amp;attrs, &amp;thread_test, (void *)&amp;struct1);
  • 我明白,如果是这样,为什么我不能创建超过 300 个线程?我已经减少了 THREADSTACK,如果我使用 fork() 我可以打开 500 多个叉子......没有意义......我必须做什么才能打开许多线程???
猜你喜欢
  • 1970-01-01
  • 2014-04-12
  • 2012-06-16
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-18
  • 2021-09-14
相关资源
最近更新 更多