我正在写一个需要快速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
打印“ got spin lock”。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
标志并继续。我不必担心一致性。
自旋锁是否具有鲁棒性?