void foo ( Bar* bar , void(Bar::*qux)(void) )
{
if ( bar )
{
bar->qux();
}
}
Проблема в:
bar
можно удалить после проверка другим потоком.
Я не могу добавить мьютекс Bar
для того, чтобы заблокировать это.
Поэтому мне интересно, могу ли я сказать процессору, чтобы эта функция выполнялась атомарно, и как бы я это сделал? Я провел много времени в Google, но не нашел понятных руководств …
Постскриптум Debian, GCC, Boost НЕ разрешено, C ++ 11 ЯВЛЯЕТСЯ позволил.
Концепция атомарных методов не существует в C ++, как в Java, где вы можете определить метод как синхронизированный. Наиболее близким к этому в C ++ было бы создание класса ScopedMutex следующим образом:
class ScopedMutex {
public:
ScopedMutex(pthread_mutex *m) : theMutex_(m) {pthread_mutex_lock(theMutex_);}
~ScopedMutex() { pthread_mutex_unlock(theMutex_); }
// Add appropriate copy constructors and operator=() to disallow mutex copy
// Or consider passing in a reference
private:
pthread_mutex *theMutex_;
};
Затем используйте это в своей функции:
void foo ( Bar* bar , void(Bar::*qux)(void) )
{
ScopedMutex m(&aMutex); // This mutex must be defined/initialized elsewhere
if ( bar )
{
bar->qux();
}
// The ScopedMutex goes out of scope when the function does,
// thus releasing the lock
}
Но это не принесет вам пользы, если вы не используете тот же мьютекс в любом другом методе, который использует объект bar.
Mutex с областью действия особенно полезен, когда у вас есть функция со сложной логикой, где есть несколько операторов возврата, поэтому вам не нужно вручную разблокировать мьютекс, он будет разблокирован, когда функция выйдет из области видимости.
Вы, вероятно, хотите использовать умный указатель с семантикой совместного владения (например, shared_ptr
, intrusive_ptr
), чтобы убедиться, что объект остается живым, пока вы на него ссылаетесь.
Вы хотите временно поделиться правами собственности на объект, чтобы предотвратить его удаление другим потоком. Это работа для shared_ptr
, с помощью weak_ptr
чтобы разрешить удаление, когда нам не нужен доступ к нему:
void foo ( std::weak_ptr<Bar> weak_bar , void(Bar::*qux)(void) )
{
if (std::shared_ptr<Bar> bar = weak_bar.lock())
{
// We now share ownership of the object - it won't be deleted
bar->qux();
}
// We have released ownership - it can now be deleted
}
Конечно, вам все еще нужна синхронизация, если нескольким потокам необходим доступ к объекту; это только решает проблему удаления, указанную в вопросе.
Извините, но не. C ++ не имеет ничего, чтобы поддержать это. Вам не обязательно добавлять мьютекс в Bar
, но, чтобы избежать этого, вам, вероятно, понадобится обертка вокруг Bar
или что-то в этом порядке.
У меня тоже есть требование для выполнения 2-х функций атомарно в Thread-1.
Основная тема:
CMythread* pThread = GetThreadFromPool();
//allocate work to thread
pThread->ResumeThread();
Тема-1:
AddtoThreadPool(this);
SuspendThread(); //sleep infinitely unless awakened by Main Thread
Проблема:
Основной поток может возобновить поток в пуле до его приостановки.
и Thread-1 (поток пула) может приостановить себя бесконечно.
Решение:
1. Выполните 2 функции в Thread-1 атомарно. Никакое количество защиты не будет работать.
2. Периодически проверяйте пул потоков, чтобы возобновить приостановленный поток, которому была выделена работа.
Спасибо за ваши ответы.
Аджай