Код: Выделить всё
// lock_and_crash.c
#include
#include
#include
#include
#include
#include
#include
typedef struct {
pthread_mutex_t mutex;
int data;
} shared_data_t;
int main() {
const char *shm_name = "/robust_mutex_shm";
// Open or create shared memory
int shm_fd = shm_open(shm_name, O_CREAT | O_RDWR, 0600);
if (shm_fd == -1) {
perror("shm_open");
return 1;
}
// Resize shared memory to hold shared_data_t
ftruncate(shm_fd, sizeof(shared_data_t));
// Map shared memory
shared_data_t *shared = mmap(NULL, sizeof(shared_data_t),
PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (shared == MAP_FAILED) {
perror("mmap");
return 1;
}
close(shm_fd);
// Zero-initialize shared memory once (mutex and data)
memset(shared, 0, sizeof(shared_data_t));
// Initialize robust mutex only once
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
if (pthread_mutex_init(&shared->mutex, &attr) != 0) {
perror("pthread_mutex_init");
return 1;
}
pthread_mutexattr_destroy(&attr);
printf("Process 1: locking mutex...\n");
if (pthread_mutex_lock(&shared->mutex) != 0) {
perror("pthread_mutex_lock");
return 1;
}
printf("Process 1: mutex locked, simulating crash (exit without unlock)...\n");
// Crash by exiting without unlocking
_exit(1);
}
Код: Выделить всё
// recover_mutex.c
#include
#include
#include
#include
#include
#include
#include
#include
typedef struct {
pthread_mutex_t mutex;
int data;
} shared_data_t;
int main() {
const char *shm_name = "/robust_mutex_shm";
int shm_fd = shm_open(shm_name, O_RDWR, 0600);
if (shm_fd == -1) {
perror("shm_open");
return 1;
}
shared_data_t *shared = mmap(NULL, sizeof(shared_data_t),
PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (shared == MAP_FAILED) {
perror("mmap");
return 1;
}
close(shm_fd);
printf("Process 2: trying to lock mutex...\n");
int ret = pthread_mutex_lock(&shared->mutex);
if (ret == EOWNERDEAD) {
printf("Process 2: EOWNERDEAD received, recovering...\n");
// Optionally recover shared data
shared->data = 12345;
// Mark mutex consistent
pthread_mutex_consistent(&shared->mutex);
pthread_mutex_unlock(&shared->mutex);
printf("Process 2: recovery complete and mutex unlocked.\n");
} else if (ret != 0) {
fprintf(stderr, "pthread_mutex_lock failed with %d (%s)\n", ret, strerror(ret));
return 1;
} else {
printf("Process 2: locked mutex normally.\n");
pthread_mutex_unlock(&shared->mutex);
}
munmap(shared, sizeof(shared_data_t));
shm_unlink(shm_name);
return 0;
}
< /code>
Вы можете создать и запустить их, например, < /p>
gcc lock_and_crash.c -o lock_and_crash -pthread
gcc recover_mutex.c -o recover_mutex -pthread
./lock_and_crash
./recover_mutex
Код: Выделить всё
...
printf("Process 1: mutex locked, simulating crash (exit without unlock)...\n");
munmap(shared, sizeof(shared_data_t));
// Crash by exiting without unlocking
_exit(1);
Подробнее здесь: https://stackoverflow.com/questions/797 ... adlock-why