Сомневаюсь, что вы можете добиться того, что вы хотите красиво на C (если вы не хотите изменить компилятор).
Вы говорите, что хотите использовать стиль программирования OpenMP. Это равносильно одному потоку верхнего уровня, который может развить детей для работы в общем пространстве, предоставляемом родителем. Необычный OpenMP делает это рекурсивно.
Для этого красиво, вы система/инструменты/компилятор должен быть в состоянии идентифицировать
* threads of computations
* what variables are declared by each thread
* what variables (or parts thereof) are offered by a thread to its thread children
Если вы можете сделать эти вещи (и проще с поддержкой явного языка, OpenMP включена компиляторы помогают в этом процессе по прагмах OpenMP), то вы можете разделить данные на волоске в в 3-х частей:
1. storage accessed only by the thread, and not by its children
2. storage declared by the thread, but accessed only by individual children (e.g., slices of arrays)
3. storage read and written by the parent thread and its children
на данный момент, вы можете рассмотреть макет из «локальные переменные» для потока, и, таким образом, чтобы стек пространство , Резервное хранилище нити распределено только в пространство стека родительского потока. Родительское, но обработанное дочерними элементами хранилище становится пространством, выделенным для локального пространства/стека. Хранение, прочитанное и написанное всеми, может быть размещено в любом месте, к которому он может быть доступен (в локальном пространстве родительского потока, в его стеке, в хранилище кучи), и для защиты данных требуется защита доступа. [Вы не можете принуждать традиционных компиляторов C сделать это для вас.]
Это разбиение данных на разные области локального/стекового потока делает вашу очевидную схему использования C и установки «всех потоков потоков» на один место в общей памяти трудно использовать. Если все потоки имеют одну и ту же область стека, какое хранилище является локальным для потока? В частности, если два потока каждый хотят записать в свою локальную переменную I, а я - в общем пространстве, то это не является локальным. Если вы разделяете разделяемое пространство на несвязанные стеки потоков, то на самом деле вы не имеете общего доступа к хранилищу, по крайней мере, не по имени; в лучшем случае вы можете делиться с помощью указателей на другие потоки потоков. Все это будет сложно запрограммировать, поэтому ошибка подвержена ошибкам, и я бы не захотел отлаживать программы, написанные для такой системы. Это также добавляет дополнительный спрос на ваше драгоценное общее пространство; у вас есть нить-локальные переменные, которые его едят, но не нуждаются в совместном использовании.
Если у вас есть статическое число потоков и продолжайте настаивать на использовании какого-либо доступного компилятора C, вам может быть лучше назначить общие данные (динамически во время выполнения или во время кодирования/компиляции разделение разделяемой памяти). Но ваши потоки теперь могут работать со своим «стандартным» стеком в своих локальных памяти, и переключение стека не требуется.
[EDIT: После моего комментария о стеках кактусов, OP хотел узнать больше. Я буду включать здесь, а также некоторые указатели к ним]
Стек может использоваться несколькими потоками. Понятие стека кактусов - это тот, в котором родительский поток, имеющий существующий (кактус) стек, делится со всеми своими параллельными дочерними элементами, каждый из которых получает собственное пространство стека, но может видеть/совместно использовать стек родителя.
Наш параллельный язык программирования PARLANSE реализует эту концепцию напрямую, и мы используем ее в прикладных программах, которые составляют порядка 2-4 миллионов строк кода. Каждая функция вызывает кучу - выделяет свои записи активации (используя локальный распределитель потока для скорости) и имеет доступ ко всем сегментам родительского стека с помощью лексического уровня до адресации, реализуемой как поле указателей, переданных родителем его дочернему элементу на вызов функции. В блоге Intel ниже описаны именно те причины, по которым мы это сделали.
Ссылки:
Что вам нужно это? Хотите, чтобы все темы использовали тот же стек? нет никакого способа, который когда-либо будет работать. Хотите передать указатели на вещи в один стек на другой поток? плохая идея, последствия синхронизации убьют вас. Хотите иметь общий стек, где любой поток может нажать/поп-вещи, теперь это совсем другая история. Поэтому, пожалуйста, уточните, чего вы на самом деле хотите достичь. – cmaster
Моя идея с использованием общего стека для связи между потоками путем передачи указателей. Идея заключается в отправке указателя общей переменной на другой процессор по сообщению. Затем процессор мог получить доступ к этому общему адресу без необходимости копировать данные в свое пространство. – Hayder
Кроме того, я не хочу использовать malloc или другую форму для распределения данных и передачи его указателя. Мне нужно выполнить процедуру, аналогичную модели OpenMP. – Hayder