🔥 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.