【问题标题】:I'm getting `Cannot allocate memory` error after mutiple pthread_create calls多次 pthread_create 调用后出现“无法分配内存”错误
【发布时间】:2017-11-18 01:45:26
【问题描述】:

我正在使用 Posix 线程并编写了以下代码,我在其中创建了很多线程,但为此目的重用了 pthread_t 变量:

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>

// The amount of thread creation iterations
static const int N = 300;

static pthread_t thread_1, thread_2, thread_3;

void * logic_1(void * arg)
{
  usleep(1 * 1000);
  printf("logic_1 end\n");
  return 0;
}

void * logic_2(void * arg)
{
  usleep(1 * 1000);
  printf("logic_2 end\n");
  return 0;
}

void * logic_3(void * arg)
{
  usleep(1 * 1000);
  printf("logic_3 end\n");
  return 0;
}

int main()
{
    int counter = 0;
    int i;
    for(i = 0; i < N; ++i)
    {
        if (pthread_create(&thread_1, NULL, &logic_1, NULL) != 0)
        {
          perror("error: ");
          printf("thread1 did not start after %d threads that were started\n", counter);
          break;
        }
        else
        {
            ++counter;
            printf("start %d thread\n", counter);
        }
        if (pthread_create(&thread_2, NULL, &logic_2, NULL) != 0)
        {
          perror("error: ");
          printf("thread2 did not start after %d threads that were started\n", counter);
          break;
        }
        else
        {
            ++counter;
            printf("start %d thread\n", counter);
        }
        if (pthread_create(&thread_3, NULL, &logic_3, NULL) != 0)
        {
          perror("error: ");
          printf("thread3 did not start after %d threads that were started\n", counter);
          break;
        }
        else
        {
            ++counter;
            printf("start %d thread\n", counter);
        }                      
        usleep(500 * 1000);
    }
    pthread_join(thread_1, NULL);
    pthread_join(thread_2, NULL);
    pthread_join(thread_3, NULL);
    return 0;
}

执行后我得到了错误:

...
start 376 thread
start 377 thread
start 378 thread
logic_3 end
logic_2 end
logic_1 end
start 379 thread
start 380 thread
start 381 thread
logic_3 end
logic_2 end
logic_1 end
error: : Cannot allocate memory
thread1 did not start after 381 threads that were started

你能告诉我我做错了什么吗?我认为我在 linux 中遇到了一些界限或限制?每次调用logic_1logic_2logic_3 函数中的return 0; 语句后,线程的资源是否会被释放?也许我应该使用一个线程数组,并为这个数组的每个项目调用pthread_join 函数?

【问题讨论】:

  • 每个线程都有自己的堆栈。默认情况下,此堆栈非常大,大约为 8 兆字节。如果线程分离,当线程退出时堆栈被丢弃。如果线程是joinable,当线程加入时堆栈被丢弃。默认情况下,线程是可加入的。因为您保留了您创建的每个线程的堆栈,所以您最终会耗尽内存。如果您想确定这一点,请创建一个打开/proc/self/maps 并使用fgetc()/putchar() 循环读取和打印其内容的函数;您将在输出中看到堆栈段。

标签: c linux multithreading unix pthreads


【解决方案1】:

您应该在循环内部而不是外部调用 pthread_join,以便在下一次迭代中启动新线程集之前释放分配的资源 如果您不加入线程,则根据 pthread_join 手册页,您将丢失系统资源

   Failure to join with a thread that is joinable (i.e., one that is not
   detached), produces a "zombie thread".  Avoid doing this, since each
   zombie thread consumes some system resources, and when enough zombie
   threads have accumulated, it will no longer be possible to create new
   threads (or processes).

【讨论】:

    猜你喜欢
    • 2017-07-15
    • 2021-01-26
    • 2011-08-02
    • 2011-07-14
    • 1970-01-01
    • 2018-03-29
    • 2010-11-16
    • 2017-06-14
    • 2018-05-15
    相关资源
    最近更新 更多