назначение в приложении pthreads - PullRequest
1 голос
/ 11 мая 2011

У меня есть многопоточное приложение linux на C ++.В этом приложении в class App предлагается переменная Status:

class App {
...
typedef enum { asStop=0, asStart, asRestart, asWork, asClose } TAppStatus;
TAppStatus Status; 
...
}

Все потоки часто проверяют Status, вызывая функцию GetStatus().

inline TAppStatus App::GetStatus(){ return Status };

Другие функцииПриложение может назначать различные значения переменной Status, вызывая функцию SetStatus() и не использовать мьютексы.

void App::SetStatus( TAppStatus aStatus ){ Status=aStatus };

Редактировать: Все потоки используют оператор Status в switch:

switch ( App::GetStatus() ){ case asStop: ... case asStart: ... };
  1. Является ли присвоение в этом случае атомарной операцией?
  2. Это правильный код?

Спасибо.

Ответы [ 3 ]

3 голосов
/ 11 мая 2011

В C99 или C ++ 03 нет переносимого способа реализации синхронизированных переменных, и библиотека pthread также не предоставляет его.Вы можете:

  • Использовать заголовок C ++ 0x <atomic> (или C1x <stdatomic.h>).Gcc поддерживает его для C ++, если задана опция -std=c++0x или -std=gnu++0x начиная с версии 4.4.
  • Использовать специфичную для Linux <linux/atomic.h> (это реализация, используемая ядром, но ее следует использовать из пользовательского пространства какхорошо).
  • Использовать специфичные для GCC __sync_* встроенные функции .
  • Использовать другую библиотеку, которая обеспечивает элементарные операции, такие как glib .
  • Используйте блокировки, но это на несколько порядков медленнее по сравнению с самой быстрой операцией.

Примечание. Как отметил Мартиньо, хотя они называются «атомарными», для хранения и загрузки это не так.атомарное свойство (операция не может быть прервана, и загрузка всегда видит или не видит целое хранилище, что обычно справедливо для 32-битных хранилищ и загрузок), но свойство упорядочения (если вы храните a и чем b, никто не может получить новое значениеб и чем старое значение а), которое трудно получить, но необходимо в этом случае.

0 голосов
/ 11 мая 2011

В некоторых архитектурах это назначение может быть атомарным (случайно), но даже если это так, этот код неверен.Компилятор и оборудование могут выполнять различные оптимизации, что может нарушить эту «атомарность».Посмотрите на: http://video.google.com/videoplay?docid=-4714369049736584770#

Используйте блокировки или атомарные переменные http://www.stdthread.co.uk/doc/headers/atomic/atomic.html, чтобы исправить это.

0 голосов
/ 11 мая 2011

Это полностью зависит от выбранного представления enum. Я полагаю, что для x86 все операции присваивания размера слова операционной системы (то есть 32-битной для x86 и 64-битной для x64) и выравнивания этого размера также являются атомарными, поэтому простое чтение и запись атомарны.

Даже если предположить, что это правильное выравнивание по размеру и , это не означает, что эти функции являются поточно-ориентированными, зависит от того, для чего используется состояние.

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

Изменить для редактирования: Нет, это не потокобезопасность вообще. Если вы преобразуете его вручную в таблицу переходов, тогда вы можете быть поточно-ориентированными, мне нужно немного подумать об этом.

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