Многопоточные многопоточные предложения анимации в c ++ - PullRequest
1 голос
/ 07 июня 2011

У меня есть программа анимации на основе таймера, запуск которой запланирован в рабочем потоке.Программа была разработана для того, чтобы постоянно запускаться при запуске.У меня также есть поток создания изображения, который отвечает за обработку изображения, а затем передает каждое обработанное изображение (в формате JPEG / PNG) в поток анимации, чтобы принять участие в цикле изображения без вмешательства пользователя.Это типичная программа с зацикливанием изображений на основе памяти.То есть все выбранные пользователем изображения загружаются в оперативную память заранее.Я использую контейнер карты для управления последовательностью изображений, объявленной в формате std :: map, которая связывает имена файлов изображений типа Key с указателями CBitmap типа Data.Я также использую строку vecter (объявленную как std :: vector), чтобы сохранить копию списка файлов изображений в отсортированном порядке, соответствующем вышеупомянутому списку ключей карты, чтобы повторять каждое изображение по порядковому номеру.Это может быть не нужно.Что касается управления анимацией, допускаются следующие киоскоподобные операции (некоторые сопровождаются объявлениями соответствующих переменных):

bool m_bPlay;   // Play forward
bool m_bPause; // Pause animation
bool m_bStop;  // Stop animation
bool m_bReverse; // Play backward
bool m_bRepeat; // Repeated play when reaching to last image
DWORD m_dwFrom;  // Starting image number
DWORD m_dwTo;    // Ending image number
DWORD m_dwCurrent;  // Current image number
DWORD m_dwFPS;   // Frames per second

Где переменная m_dwTo может быть изменена пользователем с помощью кнопки прокрутки, встроенной в панель инструментов, в верхней части главного окна графического интерфейса пользователя, или увеличенной автоматически приложением каждый раз, когда вновь обработанное изображение добавляется в вышеупомянутую карту кака также векторные контейнеры.Аналогично, переменная m_dwFrom также может быть изменена вручную так же, как и m_dwTo, или автоматически уменьшена приложением, когда истекает срок действия одного или нескольких изображений в процессе воспроизведения на основе пользовательской конфигурации скользящего архива (например, сохранитьизображений за 3 дня), и в то же время просроченные изображения должны быть удалены из вышеупомянутой карты и векторных контейнеров.Переменная m_dwFPS может быть изменена пользователем в любое время в процессе зацикливания изображения с помощью раскрывающегося списка, встроенного в панель инструментов, расположенную в верхней части главного окна графического интерфейса пользователя.Спасибо, что нашли время, чтобы прочитать длинное объяснение, которое я хочу сделать.Я надеюсь, что это поможет вам ответить на мои следующие вопросы:

  1. Для того, чтобы сделать потоки m_dwFrom, m_dwTo, m_dwCurrent и m_dwFPS более эффективными и повысить производительность с помощью InterlockedExchange или InterlockedCompareExchange, чем с использованием других блокировок, таких как CriticalSection, Mutex и т. Д..?
  2. Как сделать поток std :: map и std :: vector безопасным?Использовать только традиционные блокировки или лучше сочетать их с барьером переупорядочения компилятора (например, _ReadWriteBarrier forVisual C ++) и / или барьером переупорядочения процессора (например, семейство процессоров MemoryBarrier x86 и x64)?

Я с нетерпением жду ваших предложений.Фрагменты кода или ложного кода высоко ценятся.Заранее спасибо!Голден Ли

1 Ответ

0 голосов
/ 07 июня 2011

Я могу ошибаться, но насколько я могу догадаться из вашего описания, я бы пошел с традиционными блокировками и мьютексами, чтобы сделать ваш общий вектор и карту так же, как и другие ваши общие переменные, безопасными для потоков.Это просто самый простой способ, и ваш сценарий не кажется настолько интенсивным, чтобы оправдать что-либо более сложное.Я бы только коснулся чего-нибудь более причудливого, если бы профилирование показало, что традиционная блокировка становится проблемой производительности!

Как обеспечить безопасность потоков std :: map и std :: vector?

Обычный способ сделать это - просто написать блокирующую оболочку вокруг функций контейнера, к которым вам нужен доступ.Например:

class myAnimationManager{
private:
std::map<std::string, CBitmap*> m_imagesMap;
Mutex m_mutex;

public:
CBitmap * getImageByName(const std::string & _name)
{
ScopedLock l(m_mutex); //lock image map access
return m_imagesMaps[_name];
}
//...
};

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

...