pthreads
Főnév
pthreads (tsz. pthreadses)
- (informatika) A Pthreads (POSIX Threads) egy POSIX-szabványnak megfelelő szálkezelési (threading) API, amelyet C és C++ nyelvekben használnak párhuzamos programozáshoz Unix-szerű rendszereken (Linux, BSD, macOS). A
pthread(POSIX thread) használatával programjaink több szálat hozhatnak létre, amelyek együtt, párhuzamosan futnak, és megoszthatják a memóriát.
📌 Alapfogalmak
- Szál (thread): egy folyamaton (processzen) belüli önálló végrehajtási egység.
- Folyamat (process): operációs rendszer által menedzselt futó program, saját memóriatérrel.
- A Pthreads lehetővé teszi, hogy egy folyamaton belül több szál párhuzamosan fusson, és együtt osszanak meg változókat, erőforrásokat.
🧰 Fő funkciók (POSIX Threads API)
A pthread API funkciói pthread_ prefix-szel kezdődnek.
| Funkció | Leírás |
|---|---|
pthread_create |
új szál létrehozása |
pthread_join |
szál befejezésének megvárása |
pthread_exit |
szál befejezése |
pthread_mutex_* |
mutex kezelés (zárolás) |
pthread_cond_* |
feltételes változók |
pthread_detach |
szál „leválasztása” (nem kell join-olni) |
🔧 Alap C példa
#include <pthread.h>
#include <stdio.h>
void* hello(void* arg) {
printf("Hello from thread!\n");
return NULL;
}
int main() {
pthread_t t1;
pthread_create(&t1, NULL, hello, NULL);
pthread_join(t1, NULL);
return 0;
}
Mit csinál?
pthread_create: létrehoz egy új szálat, amely ahello()függvényt futtatjapthread_join: megvárja, amíg a szál befejeződik
🛑 Szinkronizáció: Mutex
Ha több szál megosztott változókat módosít, versenyhelyzet (race condition) léphet fel. A mutex (mutual exclusion) egy zárolási mechanizmus, amely biztosítja, hogy egyszerre csak egy szál férhessen hozzá a kritikus szakaszhoz.
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void* increment(void* arg) {
pthread_mutex_lock(&lock);
// kritikus szakasz
counter++;
pthread_mutex_unlock(&lock);
return NULL;
}
⚙️ Példa: számláló szálakkal
#include <pthread.h>
#include <stdio.h>
int counter = 0;
pthread_mutex_t lock;
void* worker(void* arg) {
for (int i = 0; i < 10000; ++i) {
pthread_mutex_lock(&lock);
counter++;
pthread_mutex_unlock(&lock);
}
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_mutex_init(&lock, NULL);
pthread_create(&t1, NULL, worker, NULL);
pthread_create(&t2, NULL, worker, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Final counter: %d\n", counter);
pthread_mutex_destroy(&lock);
return 0;
}
Kimenet: garantáltan 20000, mert a mutex védi az increment műveletet.
🔁 pthread_create szintaxisa
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine)(void *),
void *arg);
thread: ide kerül a szál-azonosítóattr: attribútum (általában NULL)start_routine: a függvény, amit a szál futtatarg: argumentum a függvényhez (void*)
⏳ pthread_join
int pthread_join(pthread_t thread, void **retval);
- Megvárja a
threadszál végét retval: a visszatérési érték (ha kell)
🧠 pthread_cond_t – Feltételes változó
A pthread_cond_t lehetővé teszi, hogy egy szál várjon bizonyos feltételre, és egy másik szál felébressze:
Példa (producer-consumer stílus):
pthread_mutex_t mutex;
pthread_cond_t cond;
bool ready = false;
void* waiter(void* arg) {
pthread_mutex_lock(&mutex);
while (!ready)
pthread_cond_wait(&cond, &mutex);
printf("Ready!\n");
pthread_mutex_unlock(&mutex);
return NULL;
}
void* notifier(void* arg) {
pthread_mutex_lock(&mutex);
ready = true;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return NULL;
}
⚠️ Tipikus hibák
- Elfelejtett zárolás: versenyhelyzethez vezethet
- Halott zárolás (deadlock): több mutex egymásba akad
- Szál elfelejtése
join-olni: memória és vezérlés kiszámíthatatlansága - Éhezés (starvation): egyik szál sosem fér hozzá a zárolt erőforráshoz
📚 Tippek
- Ne használd globális változókat védelem nélkül
- Mindig párosítsd
pthread_mutex_lock()-otunlock()-kal – akár kivételes útvonalon is - Használj
pthread_cond_*feltételes változókat a komplex várakozásra - Szálak számát és állapotát mindig dokumentáld jól – a hibakeresés különben pokoli
🧵 pthread vs std::thread (C++11+)
| Tulajdonság | pthread |
std::thread (C++) |
|---|---|---|
| Nyelv | C | C++11 és újabb |
| Hordozhatóság | POSIX-only | Platformfüggetlen (elvben) |
| API | Alacsony szintű | Magasabb absztrakció |
| Könnyű használat | ❌ | ✅ |
🧪 Cigarette Smokers + Pthreads?
Igen, a Cigarette Smokers Problem is remekül megvalósítható pthread_create, pthread_mutex_t, pthread_cond_t használatával. A lényege, hogy:
- Az ügynök szál feltételes változókkal jelez a dohányosoknak
- A dohányosok külön-külön mutex + cond párokkal várnak
- A kritikus szakasz: csak egy dohányos dolgozhat egyszerre
🔚 Összegzés
A Pthreads egy erős, de alacsony szintű eszköztár a C/C++ programozóknak, ha párhuzamos, szál-alapú programozásban gondolkodnak. Előnye, hogy közvetlen hozzáférést ad a rendszer erőforrásaihoz és viselkedéséhez, de cserébe nagyobb felelősséget is ró a programozóra. Hibakezelés, szinkronizáció és adatversenyek megelőzése elengedhetetlen!