У меня есть два потока, один поток запускает цикл, чтобы проверить, есть ли данные, полученные в ожидании на нескольких сокетах, а другой поток пытается добавить сокет в список сокетов или удалить его.
Код выглядит следующим образом:
Тема 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, когда есть поток, ожидающий блокировки?
Как насчет:
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);
}
void AddSocket(Socket* socket)
{
AutoLock addLock(_addLock);
AutoLock socLock(_socketsLock);
_sockets.push_back(socket);
}
usleep()
работает. Он эффективно переводит этот поток в спящий режим, поэтому ОС находит другой доступный поток, который может работать.