Как открыть много общих библиотек в другом потоке, используя dlmopen? - PullRequest
0 голосов
/ 22 января 2019

Мне нужно загружать разделяемую библиотеку столько раз, сколько нужно во время выполнения (> 100000) в другом потоке для параллельного выполнения. У меня нет доступа к источнику этой общей библиотеки, и она использует много глобальных переменных. Вот почему я хотел бы загрузить X раз эту общую библиотеку.

Я пытаюсь сделать это с помощью dlmopen, но на самом деле это может показаться из моего теста, который ограничен примерно 15 dlmopen одновременно.

void launch(int num) {
    void (*test)(int);
    char *error;

    void *handle = dlmopen(LM_ID_NEWLM, "/path/to/lib/libshared.so", RTLD_LAZY | RTLD_LOCAL);
    if (handle == NULL) {
        std::cout << "Load shared lib [FAILED] in thread: " << num << std::endl;
        return ;
    }
    dlerror();
    *(void **) (&test) = dlsym(handle, "thread");
    if ((error = dlerror()) != NULL)  {
        fprintf(stdin, "%s\n", error);
        exit(EXIT_FAILURE);
    }
    (*test)(num);
    dlclose(handle);
}

int main(int ac, char **av) {
    try {
        std::vector<std::thread *> vec;
        for (int counter = 0; counter < 100; ++counter) {
            std::thread *t1 = new std::thread(launch, counter);
            vec.push_back(t1);
        }

        for (std::vector< std::thread* >::iterator it = vec.begin() ; it != vec.end(); ++it) {
            (*it)->join();
            delete (*it);
        }
        vec.clear();
    } catch(std::exception const &e) {
        std::cerr << "[ERROR]: " << e.what() << std::endl;
        return(EXIT_FAILURE);
    }
    return 0;
}

Сбой вызова dlmopen после выполнения 15 потоков, у вас есть идея или другой способ сделать это?

1 Ответ

0 голосов
/ 23 января 2019

После исследования кажется, что при запуске программы динамический компоновщик вычисляет все смещения и гарантирует, что все потоки имеют достаточно места для всех требуемых локальных переменных потока.

С dlopen это не работаетв общем, потому что невозможно переместить блок управления потоком, чтобы освободить место для большего количества локальных переменных потока.Текущий динамический компоновщик glibc резервирует некоторое пространство для будущих вызовов dlopen, но если вы загружаете несколько общих объектов, каждый из которых имеет свои собственные локальные переменные потока, этого недостаточно. Поэтому я получаю «не могу выделить память в статическом блоке TLS».

Реализация glibc поддерживает максимум 16 пространств имен.Я должен найти другое решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...