Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Синхронизация потоков @ Родной Android

Автор вопроса: NadavRubОтветов: 2

Windows CRITICAL_SECTION реализована проще, чем мьютекс (что касается затрат на блокировку/разблокировку). За счет использования спин-блокировки и семафора для уменьшения числа переключений пользователя/ядра.

Мьютекс требует переключения контекста, даже если мьютекс в настоящее время не принадлежит / не заблокирован, где CRITICAL_SECTION потребует этого только после определенного периода времени, находящегося в блокировке спина (приводит к лучшей производительности).

Я новичок в Android Native dev, имея в виду Windows CRITICAL_SECTION, есть ли эквивалент в Native Android?

Есть ли что-нибудь легче, чем pthread_mutex_. @ Android? делает ли 'pthread_mutex_.' переключение контекста, даже если мьютекс еще не ~владел/заблокирован~ (как в Windows)?

Имея в виду быстрый вход/выход из критической секции Какова стоимость использования 'pthread_mutex_.'?

Есть ли спин-блокировка пользовательского режима @ Native Android?

Любая помощь будет оценена.

Надав в Софине

  • есть ли у вас какое-либо представление о блокировке/разблокировке устройства Android на собственном уровне, то есть на c/c++. CoDe 08.06.2012

linux-kernelandroidandroid-ndkpthreads

Ответы

Ответ 1 · рейтинг 5 · caf

Нет, pthread_mutex_lock() в Android Bionic libc не навязывает переключение контекста для блокировки обычного мьютекса в неконкурентном состоянии - используется простое атомарное сравнение и обмен, за которым следует барьер памяти. Точно так же разблокировка мьютекса не требует входа в ядро, если его не ожидает процесс.

Вы можете найти реализацию Bionic pthread_mutex_lock() и pthread_mutex_unlock() в libc/bionic/pthread.c в исходниках Bionic libc и убедиться в этом сами.

В общем, вы можете считать pthread_mutex_lock() / pthread_mutex_unlock() довольно легкими.

Ответ 2 · рейтинг 3 · Gavin

Ниже приведен некоторый мьютекс pthread инкапсуляции в стиле Windows CRITICAL_SECTION.

typedef struct tagCRITICAL_SECTION {
  pthread_mutex_t     _mutex;
  pthread_mutexattr_t _mutexattr;
} CRITICAL_SECTION, *LPCRITICAL_SECTION;


static inline
VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection) {
  //  printf("[init]  %0x\n", (UINT)lpCriticalSection);
  int ret;
  ret = pthread_mutexattr_init(&(lpCriticalSection->_mutexattr));
  assert(ret==0);
#if defined (__APPLE__) || defined(__linux__)
    pthread_mutexattr_settype(&lpCriticalSection->_mutexattr, PTHREAD_MUTEX_RECURSIVE);
#elif ANDROID
    // Do nothing
#else
  lpCriticalSection->_mutexattr.__mutexkind = PTHREAD_MUTEX_RECURSIVE_NP;
#endif
  ret = pthread_mutex_init(&(lpCriticalSection->_mutex),
                           &(lpCriticalSection->_mutexattr));
  assert(ret==0);
}

static inline
VOID DeleteCriticalSection    (LPCRITICAL_SECTION lpCriticalSection) {
  int ret;
  ret = pthread_mutex_destroy    (&(lpCriticalSection->_mutex));
  assert(ret==0);
  ret = pthread_mutexattr_destroy(&(lpCriticalSection->_mutexattr));
  assert(ret==0);
}

static inline
VOID EnterCriticalSection     (LPCRITICAL_SECTION lpCriticalSection) {
  int ret;
  ret = pthread_mutex_lock(&(lpCriticalSection)->_mutex);
  assert(ret==0);
}

static inline
BOOL TryEnterCriticalSection     (LPCRITICAL_SECTION lpCriticalSection) {
  int ret;
  ret = pthread_mutex_trylock(&(lpCriticalSection)->_mutex);

  return ret == 0;
}

static inline
VOID LeaveCriticalSection     (LPCRITICAL_SECTION lpCriticalSection) {
  int ret;
  ret = pthread_mutex_unlock(&(lpCriticalSection->_mutex));
  // ret==1 means mutex is owned by another thread!
}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы