pthread_unlock_mutex не просыпается в ожидании

0

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

Код выглядит следующим образом:

Тема 1:

while (!stop)
{
    // usleep(0)
    AutoLock lock(_socketsLock); // AutoLock will call pthread_lock_mutex/pthread_unlock_mutex.
    Socket* activeSockets = waitOnSockets(_sockets, 50); // Wait 50ms for data on the socket list.
    // Handle the data from socket.
}

Тема 2:

void AddSocket(Socket* socket)
{
     AutoLock lock(_socketsLock);
     _sockets.push_back(socket);
}

Проблема заключается в AddSocket швы AddSocket не могут получить блокировку в течение длительного времени в системе Android, я запустил приложение на Mac, швы AddSocket ждут максимум для одного цикла, но на Android он может составлять 10 + секунд.

Поэтому я предполагаю, что pthread_unlock_mutex не пробуждает другой ожидающий поток на Android. Я могу добавить usleep(0) в начало цикла, чтобы решить эту проблему, даже man-страница usleep say usleep(0) будет иметь никакого эффекта.

Но если я добавлю usleep(0), всегда будет переключаться поток для каждого цикла, что, я думаю, не будет хорошо для производительности мобильных устройств.

Итак, какой альтернативный способ выпустить CPU при вызове pthread_unlock_mutex и не имеет проблемы с производительностью, а в другом слове выдает только CPU, когда есть поток, ожидающий блокировки?

  • 0
    Просто мысль. Не вдаваясь в это, я чувствую, что это пахнет как состояние гонки.
  • 0
    То, что поток теперь может блокировать, не означает, что он проснется. Поток все еще должен быть запланирован ОС. Я не уверен, сколько ядер у вашего оборудования. Но если у него есть только один, почему текущий поток должен перейти в спящий режим, чтобы запустить другой поток? Вот почему usleep() работает. Он эффективно переводит этот поток в спящий режим, поэтому ОС находит другой доступный поток, который может работать.
Показать ещё 2 комментария
Теги:
multithreading
posix
scheduler

1 ответ

1
Лучший ответ

Как насчет:

Тема 1:

while (!stop)
{
    AutoLock addLock(_addLock);
    AutoLock socLock(_socketsLock);

    // Release the addLock here.
    // This gives thread 2 an opportunity to get the first lock while this
    // thread is waiting on the socket.
    AutoRelease addRel(addLock);

    // When this thread finishes it will be forces to sleep if there are
    // any waiting AddSocket requests otherwise it will continue as normal. 
    Socket* activeSockets = waitOnSockets(_sockets, 50);
}

Тема 2:

void AddSocket(Socket* socket)
{
     AutoLock addLock(_addLock);
     AutoLock socLock(_socketsLock);

     _sockets.push_back(socket);
}
  • 0
    классное решение это полностью решило мою проблему.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню