Я пишу библиотеку, которая нуждается в быстрой блокировке ipc, вокруг небольшого критического раздела.Я хочу убедиться, что сбой в несвязанном коде во время критической секции все еще снимет блокировку ipc.
В этом примере main
создает объект общей памяти, и память отображает его.Инициализирует память как pthread_spinlock_t
с PTHREAD_PROCESS_SHARED
, позволяя нескольким процессам использовать одну и ту же блокировку.
void proc1_main() {
auto shm_obj = ...
pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
this_thread::sleep_for(chrono::seconds(2));
pthread_spin_unlock((pthread_spinlock_t*)obj.ptr);
}
void proc2_main() {
auto shm_obj = ...
this_thread::sleep_for(chrono::seconds(1));
cout << "waiting for spin lock...\n";
pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
cout << "got spin lock\n";
pthread_spin_unlock((pthread_spinlock_t*)shm_obj.ptr);
}
int main() {
auto shm_obj = ...
pthread_spin_init((pthread_spinlock_t*)shm_obj.ptr, PTHREAD_PROCESS_SHARED);
shm_obj.close();
if (::fork()) {
proc1_main();
} else {
proc2_main();
}
}
Сны гарантируют, что упорядочение процессов гарантировано (более или менее) гарантировано.
proc1
захватывает спин-блокировку. proc2
печатает «ожидание спин-блокировки ...». proc2
начинает ожидание на спин-блокировке. proc1
снимает блокировку вращения. proc2
получает блокировку вращения. proc2
печатает «получил блокировку вращения». proc2
освобождает спин-блокировку.
Это все хорошее и ожидаемое поведение для блокировки.
Меня беспокоит, что произойдет, если процесс завершится сбоем и не освободитзамок.
void proc1_main() {
auto shm_obj = ...
pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
this_thread::sleep_for(chrono::seconds(2));
// pthread_spin_unlock((pthread_spinlock_t*)obj.ptr);
}
В этой модификации proc1
завершается без снятия блокировки вращения.proc2
зависает навсегда.
Если бы я использовал pthread_mutex_t, я мог бы добавить флаг PTHREAD_MUTEX_ROBUST
и продолжить.Мне не нужно беспокоиться о согласованности.
Есть ли какая-нибудь надежность для спиновых замков?