Держите переменные pthread локальными - PullRequest
2 голосов
/ 07 ноября 2010

Есть ли способ при использовании pthread.h в GCC Linux для хранения переменных, локальных для функции потока:

int i = 42; // global instance of i    

int main() {
    pthread_t threads[2];
    long t;
    pthread_create(&threads[t], NULL, ThreadFunction, (void *) t;
    pthread_create(&threads[t], NULL, ThreadFunction2, (void *) t;
}

Интересно, есть ли параметр в функции POSIX, создающий новый поток и сохраняющий переменные локальными:

void *ThreadFunction(void *threadid)
{
    int i=0;
    i++; // this is a local instance of i
    printf("i is %d", i); // as expected: 1
}

void *ThreadFunction2(void *threadid)
{
    i += 3; // another local instance -> problem
}

Где впоследствии i равно 42. Даже если я определил i ранее, я хочу, чтобы это i не было в моих темах.

Ответы [ 4 ]

5 голосов
/ 07 ноября 2010

В gcc вы можете создать глобальную переменную thread-local, используя спецификатор __thread:

__thread int i = 42;

Не делайте этого.Есть лучшие решения, в зависимости от того, что вы хотите сделать.

3 голосов
/ 07 ноября 2010

Глобальные переменные всегда доступны во всей единице компиляции (или даже больше единиц компиляции, если вы используете внешние объявления). Это не имеет ничего общего с потоками, это стандартное поведение C / C ++. Рекомендуемое решение - не использовать глобалы - глобалы - зло. Если вам все еще нужно использовать глобальные переменные, вы можете добавить к ним префикс, например g_i. Другое решение - поместить ваши функции потоков в другой модуль компиляции (файл c).

2 голосов
/ 07 ноября 2010

Пример кода неверен (сам по себе) и имеет неопределенное поведение. Вы пытаетесь прочитать неинициализированную переменную t четыре раза - два раза для индексации массива и два раза в выражении приведения - и в зависимости от (неопределенного) значения &threads[t], функция pthread_create может вызвать больше UB .

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

Относительно переменной i: объявление новой переменной i (т. Е. int i = 0) в локальной области видимости скрывает любые возможные значения i в более широкой области видимости, поэтому при использовании * не должно возникнуть никаких проблем. 1013 * локально как имя переменной внутри функции.

1 голос
/ 07 ноября 2010

phtread имеет понятие локального хранилища потоков, а gcc предлагает простой интерфейс с классом хранения __thread.Такие переменные страдают от всех проблем глобальных переменных, а затем еще некоторых.Но иногда они удобны, так как все другие решения хуже в контексте.

...