Как я могу создать так много потоков в C ++ на Beaglebone Black - PullRequest
2 голосов
/ 22 апреля 2019

Я хочу создать более 500 потоков в c ++ на beaglebone black, но в программе есть ошибки.Не могли бы вы объяснить, почему произошли ошибки и как я могу исправить ошибки

в потоке func.: call_from_thread (int tid)

void call_from_thread(int tid)
{
    cout << "thread running : " << tid << std::endl;
}

в основной функции.

int main() {
    thread t[500];

    for(int i=0; i<500; i++) {
        t[i] = thread(call_from_thread, i);
        usleep(100000);
    }

    std::cout << "main fun start" << endl;

    return 0;
}

Я ожидаю

...
...
thread running : 495
thread running : 496
thread running : 497
thread running : 498
thread running : 499
main fun start

, но

...
...
thread running : 374
thread running : 375
thread running : 376
thread running : 377
thread running : 378
terminate called after throwing an instance of 'std::system_error'
  what():  Resource temporarily unavailable
Aborted

можетты мне помогаешь?

Ответы [ 2 ]

4 голосов
/ 22 апреля 2019

beaglebone black , по-видимому, имеет максимум 512 МБ DRAM.Минимальный размер стека потока в соответствии с pthread_create () составляет 2 МБ .

, то есть 2 ^ 29/2 ^ 21 = 2 ^ 8 = 256. Так что вы, вероятно, видите вокругПоток 374 - это то, что распределитель не может освободить память достаточно быстро, чтобы удовлетворить потребность, которая обрабатывается путем генерирования исключения.

Если вы действительно хотите увидеть это разнесение, попробуйте переместить этот вызов сна в вашу функцию потока.:)

Вы можете попробовать предварительно выделить стек 1 МБ или меньше (pthreads), , но у него есть свой собственный набор проблем .

Вопросы, которые нужно задать себе,:

  • Является ли мое приложение связанным или вычисляемым?

  • Какой у меня бюджет памяти для запуска этого приложения?Если вы потратите всю свою физическую память на стеки потоков, у вас не останется ничего для общей кучи программ.

  • Нужно ли мне много параллелизма для выполнения этой работы?Кстати, A8 - одноядерный компьютер.

  • Можно ли решить проблему с помощью пула потоков?Или вообще не использовать потоки?

Наконец, вы не можете установить размер стека в std :: thread api, но вы можете в boost :: thread ,Или просто напишите тонкую оболочку вокруг pthreads (при условии Linux).

0 голосов
/ 22 апреля 2019

Всякий раз, когда вы используете темы, есть три части.

  • Запуск потоков
  • Выполнение работы
  • Освобождение потока

Вы запускаете темы и выполняете работу,но ты их не отпускаешь.

Освобождение потоков. Существует два варианта освобождения потока.

  • Вы можете присоединиться к потоку (который в основном ожидает его завершения)
  • Вы можете отсоединить поток и позволить ему выполняться независимо.

В этом конкретном случае вы не хотите, чтобы программа заканчивала работу до тех пор, пока не завершатся все потоки, поэтому вам следует присоединиться к ним.

#include <iostream>
#include <thread>
#include <vector>
#include <string>

auto call_from_thread = [](int i) {
    // I create the entire message before printing it, so that there's no interleaving of messages between threads
    std::string message = "Calling from thread " + std::to_string(i) + '\n';
    // Because I only call print once, everything gets printed together
    std::cout << message;
};
using std::thread;


int main() {
    thread t[500];

    for(int i=0; i<500; i++) {
        // Here, I don't have to start the thread with any delay
        t[i] = thread(call_from_thread, i);
    }

    std::cout << "main fun start\n";

    // I join each thread (which waits for them to finish before closing the program)
    for(auto& item : t) {
        item.join();
    }
    return 0;
}
...