Два семафора? Загрузите один, 'A', с пределом глубины стека, создайте другой, 'B', пустым. Каждый поток, который хочет выдвинуть значение, должен ждать единицы от «A», вытолкнуть значение и затем подать сигнал единице на «B». Каждый поток, который хочет выдвинуться, должен ждать единицы от 'B', вытолкнуть значение и затем сигнализировать единицу на 'A'.
Если стек не является поточно-ориентированным, вам потребуется также мьютекс / критическая секция для защиты стека от множественного доступа.