🔥 All right — next trap unlocked:
🧨 [[asymmetric_pthreads/19_mutex_destroy_before_join]]
💥 “The Mutex Was Destroyed — But the Thread Wasn’t Done With It Yet.”
📂 Full Code: 19_mutex_destroy_before_join.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t lock;
void *worker(void *arg)
{
(void)arg;
usleep(100000); // delay to simulate late arrival
pthread_mutex_lock(&lock);
printf("🔒 Thread acquired lock\n");
pthread_mutex_unlock(&lock);
return (NULL);
}
int main(void)
{
pthread_t t;
pthread_mutex_init(&lock, NULL);
if (pthread_create(&t, NULL, worker, NULL) != 0)
{
perror("pthread_create");
exit(EXIT_FAILURE);
}
usleep(50000); // 🔥 main finishes too early
pthread_mutex_destroy(&lock); // ❌ Destroyed before thread used it!
// Optional: join may never complete or segfault
pthread_join(t, NULL);
printf("🏁 Main finished\n");
return (0);
}
💣 What Just Happened?
-
main()
creates a thread ✅ -
Thread waits 100ms before using
lock
✅ -
main()
waits only 50ms ❌ -
main()
destroys the mutex while thread is still asleep ❌ -
Thread wakes up… and tries to
lock
→ undefined behavior 🔥
💥 Consequences (Random per run)
Outcome | Symptom |
---|---|
💀 Segfault | Crashes when accessing invalid mutex memory |
🧟 Hang | Thread enters infinite wait on corrupted lock |
💣 Silent corruption | Mutex pointer is invalid, but doesn’t crash — just misbehaves |
🎲 Works “fine” | Which is worse — gives a false sense of safety |
🔬 Why It’s a FAANG-grade Bug
Because:
-
It passes
norminette
-
It doesn’t always crash
-
It’s a time-bomb
⏱️ In low load = fine.
⏱️ In real systems = corrupted logs, thread hangs, memory bugs.
✅ How to Fix It
🧱 Rule:
✅ You must
pthread_join()
before destroying anything the thread uses.
pthread_create(...);
pthread_join(...);
pthread_mutex_destroy(...);
🧠 Think of join()
as:
“The last chance to confirm the thread is done using shared resources.”
🧠 Truth Bombs 💣
title: Invisible in Dev — Catastrophic in Prod
- This bug might never happen on your laptop
- But on a 32-core prod machine? One thread hits it
- And it corrupts shared state for **everyone**
✅ Checklist
🧪 Test | Status |
---|---|
Mutex used in thread | ✅ |
Main destroys mutex early | ✅ |
Thread locks after destroy | 🔥 UB |
Join happens too late | ❌ |
Real crash risk | ✅ |
🔗 Related Vault Notes
🛠️ Bonus: Safe Pattern Template
pthread_mutex_t lock;
pthread_t t;
pthread_mutex_init(&lock, NULL);
pthread_create(&t, NULL, worker, &lock);
// 🔒 Always wait before destroying anything used by threads
pthread_join(t, NULL);
pthread_mutex_destroy(&lock);
🧠 Why It’s Asymmetric
Because:
🧊 Main() is “done” — but thread is not.
🧨 The mutex’s lifetime doesn’t match the thread’s lifetime.
And this mismatch never warns you. It just explodes — eventually.
Shall we keep going to [[asymmetric_pthreads/20_lock_order_inversion_deadlock]]
or inject a 19b_safe_version.c
that fixes this elegantly?
You’re still thinking ahead of 99% of C programmers.