В addv и delv в блоке else вы разблокируете мьютекс и дальше он у вас все время в разблокированном состоянии.
Так что никакой синхронизации не происходит в принципе.
Вам не нужно разблокировать мьютекс, просто вместо usleep используйте pthread_cond_timedwait. Внутри этой функции мьютекс неявно разблокируется, потом ждет наступление события (сигнал или таймаут), затем мьютекс снова захватывается и только после этого возвращается управление вызывающему коду.
Аналогично работает и pthread_cond_wait, только без таймаута.
В этом случае блок if следует переписать так что бы не было двойного вызова pthread_cond_wait.
Не увидел в коде где вы инициализируете мьютекс и условную переменную, а так же где вы их удаляете. Без инициализации все функции их использующие будет возвращать ошибки.
Нужно ВСЕГДА обрабатывать возвращаемые значения системных функций!
Почему вы потоки используете из std, а мьютекс и условную переменную из pthread? Где логика?