Anonymous
Munmap Shared Memory с заблокированным прочным Mutex делает его тупиком, почему?
Сообщение
Anonymous » 05 сен 2025, 17:18
Мне нужно использовать надежные мутекс для МПК на случай, если один из моих процессов вылетает, удерживая заблокированную мутекс. Определение ясно из, например, Man pthread_mutexattr_setRobust и я не буду повторять его здесь.
Код: Выделить всё
// 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);
}
2 -й процесс recovery_mutex.c
Код: Выделить всё
// 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
Однако, когда я добавляю один Munmap перед выходом в конце 1 -й процесса lock_and_crash.c :
Код: Выделить всё
...
printf("Process 1: mutex locked, simulating crash (exit without unlock)...\n");
munmap(shared, sizeof(shared_data_t));
// Crash by exiting without unlocking
_exit(1);
2-й процесс висит, pthread_mutex_lock (& shared-> mutex); никогда не возвращается. Почему? Это где -то задокументировано?
Подробнее здесь:
https://stackoverflow.com/questions/797 ... adlock-why
1757081905
Anonymous
Мне нужно использовать надежные мутекс для МПК на случай, если один из моих процессов вылетает, удерживая заблокированную мутекс. Определение ясно из, например, Man pthread_mutexattr_setRobust и я не буду повторять его здесь.[code]// 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); } [/code] 2 -й процесс recovery_mutex.c [code]// 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 [/code] Однако, когда я добавляю один Munmap перед выходом в конце 1 -й процесса lock_and_crash.c : [code]... printf("Process 1: mutex locked, simulating crash (exit without unlock)...\n"); munmap(shared, sizeof(shared_data_t)); // Crash by exiting without unlocking _exit(1); [/code] 2-й процесс висит, pthread_mutex_lock (& shared-> mutex); никогда не возвращается. Почему? Это где -то задокументировано? Подробнее здесь: [url]https://stackoverflow.com/questions/79756866/munmap-shared-memory-with-locked-robust-mutex-makes-it-deadlock-why[/url]