Если вы пишете программу на диалекте до C ++ 11, то, строго говоря, результат не будет переносимым - старые диалекты C ++ не имеют никакого понятия о потоках.
Но если вы используете C ++ 11 (чего можно достичь, сказав «Это теперь C ++ 11» без изменения одного байта и использования флага компилятора) и придерживайтесь потоковых возможностейязык (thread_local
вместо __thread
), переносимость гарантируется языком.
В реальной жизни большинство реализаций до C ++ 11 достаточно хорошо работают с потоками.Например, gcc
и x86_64
будут работать - gcc имеет встроенные механизмы для многопоточности, а x86_64 - это архитектура с сильной моделью памяти (подробнее об этом здесь в главе, посвященной упорядочению памяти).
Тем не менее, вы используете локальный поток странным образом.Обычная семантика -
__thread long array_data;
long* array[NTHREADS]; // non thread local pointer to thread local data
Теперь, если вы измените array_data
в любом потоке, будет изменена только локальная копия потока array_data
.Если вам нужен доступ к array_data
из другого потока, скажем, из супервизорного потока, который суммирует все array_data
, вам нужен массив, который содержит указатели на все локальные потоки и какие элементы инициализируются при запуске каждого потока с
array[iThread] = &array_data; // where iThread is an index for each thread
Доступ из потока супервизора будет выглядеть следующим образом:
long sum=0;
for (int i=0; i<NTHREADS; ++i)
sum += *array[i];
Необходимо убедиться, что ваш доступ к локальным потокам потоков из других потоков сериализован или, при необходимости, защищен мьютексами.В вашем случае (x86 и gcc) цикл суммирования будет просто работать - выровненные длинные строки гарантированно будут атомарными на вашем оборудовании, а gcc увидит указатель как неограниченный - но будьте осторожны.