PTHREAD(3)

πŸ“¦ version 15.1, in freebsd 14.5, freebsd 15.1, nixpkgs unstable

πŸ’… PTHREAD(3) β€” POSIX thread functions, but make it make sense πŸ’…

Okay bestie, this is the PTHREAD(3) page from the Library Functions Manual, and it’s all about the POSIX Threads Library (libpthread, -lpthread). This is part 1, so buckle up. πŸŽ€

🌸 NAME 🌸

pthread β€” POSIX thread functions. That’s the name, bestie. Periodt. πŸ’…

πŸ“š LIBRARY πŸ“š

POSIX Threads Library (libpthread, -lpthread) β€” yes, that’s the one you link with. ✨

🧚 SYNOPSIS 🧚

#include <pthread.h>

✨ DESCRIPTION ✨

Okay so POSIX threads are a set of functions that support applications with requirements for multiple flows of control, called threads, within a process. Multithreading is used to improve the performance of a program. That’s the whole vibe: multiple little flows of control doing their thing inside one process, and multithreading can make your program perform better. πŸ¦‹

The POSIX thread functions are summarized in this section in the following groups:

  • Thread Routines
  • Attribute Object Routines
  • Mutex Routines
  • Condition Variable Routines
  • Read/Write Lock Routines
  • Per-Thread Context Routines
  • Cleanup Routines

FreeBSD extensions to the POSIX thread functions are summarized in pthread_np(3). Go check that one if you need the FreeBSD-specific extras, iykyk. πŸ‘‘


🧡 Thread Routines 🧡

  • int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) β€” Creates a new thread of execution. New main character just dropped. ✨
  • int pthread_cancel(pthread_t thread) β€” Cancels execution of a thread. Sorry bestie, it’s giving cancel culture. 😭
  • int pthread_detach(pthread_t thread) β€” Marks a thread for deletion. Not me setting it free. πŸ¦‹
  • int pthread_equal(pthread_t t1, pthread_t t2) β€” Compares two thread IDs. Are they the same? Let’s find out. πŸ’…
  • void pthread_exit(void *value_ptr) β€” Terminates the calling thread. Bye from the thread itself. πŸ‘‹
  • int pthread_join(pthread_t thread, void **value_ptr) β€” Causes the calling thread to wait for the termination of the specified thread. It’s literally waiting for its friend to finish. 🫢
  • int pthread_kill(pthread_t thread, int sig) β€” Delivers a signal to a specified thread. A little signal delivery, very demure. πŸ’Œ
  • int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) β€” Calls an initialization routine once. Once. Not twice. Once. πŸ’€
  • pthread_t pthread_self(void) β€” Returns the thread ID of the calling thread. Hi, it’s me. πŸ™ˆ
  • int pthread_setcancelstate(int state, int *oldstate) β€” Sets the current thread’s cancelability state. Setting the vibe for cancellation. ✨
  • int pthread_setcanceltype(int type, int *oldtype) β€” Sets the current thread’s cancelability type. The type of cancellation energy, if you will. πŸ’…
  • void pthread_testcancel(void) β€” Creates a cancellation point in the calling thread. A little checkpoint, bestie. πŸŽ€
  • void pthread_yield(void) β€” Allows the scheduler to run another thread instead of the current one. Sharing is caring, fr fr. 🌈

πŸͺ„ Attribute Object Routines πŸͺ„

  • int pthread_attr_destroy(pthread_attr_t *attr) β€” Destroy a thread attributes object. Cleanup era. 🧹
  • int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched) β€” Get the inherit scheduling attribute from a thread attributes object. Reading the scheduling tea. 🍡
  • int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param) β€” Get the scheduling parameter attribute from a thread attributes object. Parameter peek. πŸ‘€
  • int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) β€” Get the scheduling policy attribute from a thread attributes object. Policy check. πŸ’…
  • int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope) β€” Get the contention scope attribute from a thread attributes object. Scope it out. πŸ”­
  • int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize) β€” Get the stack size attribute from a thread attributes object. How big is the stack? Asking for a friend. πŸ“
  • int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr) β€” Get the stack address attribute from a thread attributes object. Address acquired. πŸ“¬
  • int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) β€” Get the detach state attribute from a thread attributes object. Detach state check, no cap. πŸ’€
  • int pthread_attr_init(pthread_attr_t *attr) β€” Initialize a thread attributes object with default values. Fresh start, default settings. ✨
  • int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched) β€” Set the inherit scheduling attribute in a thread attributes object. Setting the inheritance vibe. 🧬
  • int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param) β€” Set the scheduling parameter attribute in a thread attributes object. Parameter, but make it set. πŸ’…
  • int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) β€” Set the scheduling policy attribute in a thread attributes object. Policy is now set. πŸ‘‘
  • int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope) β€” Set the contention scope attribute in a thread attributes object. Scope: set. πŸ”­
  • int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) β€” Set the stack size attribute in a thread attributes object. Stack size, your call. πŸ“
  • int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr) β€” Set the stack address attribute in a thread attributes object. Address, but make it set. πŸ“¬
  • int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) β€” Set the detach state in a thread attributes object. Detach state: handled. πŸ’…

πŸ”’ Mutex Routines πŸ”’

  • int pthread_mutexattr_destroy(pthread_mutexattr_t *attr) β€” Destroy a mutex attributes object. Mutex attributes? Gone. 🧹
  • int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *restrict attr, int *restrict ceiling) β€” Obtain priority ceiling attribute of mutex attribute object. Priority ceiling tea. 🍡
  • int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict attr, int *restrict protocol) β€” Obtain protocol attribute of mutex attribute object. Protocol received. πŸ“‘
  • int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restrict type) β€” Obtain the mutex type attribute in the specified mutex attributes object. Type check. πŸ’…
  • int pthread_mutexattr_init(pthread_mutexattr_t *attr) β€” Initialize a mutex attributes object with default values. Defaults, but for mutex attributes. ✨
  • int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int ceiling) β€” Set priority ceiling attribute of mutex attribute object. Ceiling: set. 🏠
  • int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol) β€” Set protocol attribute of mutex attribute object. Protocol: set. πŸ“‘
  • int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) β€” Set the mutex type attribute that is used when a mutex is created. This is the type that gets used when a mutex is created, bestie. πŸ’…
  • int pthread_mutex_destroy(pthread_mutex_t *mutex) β€” Destroy a mutex. Mutex deleted. πŸ’€
  • int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) β€” Initialize a mutex with specified attributes. Mutex debut. ✨
  • int pthread_mutex_lock(pthread_mutex_t *mutex) β€” Lock a mutex and block until it becomes available. Locked and waiting. πŸ”’
  • int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime) β€” Lock a mutex and block until it becomes available or until the timeout expires. Locked, but with a timer. ⏰
  • int pthread_mutex_trylock(pthread_mutex_t *mutex) β€” Try to lock a mutex, but do not block if the mutex is locked by another thread, including the current thread. It won’t block if the mutex is locked by another thread β€” including the current thread. Yes, even you, bestie. πŸ’€
  • int pthread_mutex_unlock(pthread_mutex_t *mutex) β€” Unlock a mutex. Release the lock, release the drama. πŸ•ŠοΈ

🫧 Condition Variable Routines 🫧

  • int pthread_condattr_destroy(pthread_condattr_t *attr) β€” Destroy a condition variable attributes object. Cond attr: destroyed. 🧹
  • int pthread_condattr_init(pthread_condattr_t *attr) β€” Initialize a condition variable attributes object with default values. Fresh cond attr, default values. ✨
  • int pthread_cond_broadcast(pthread_cond_t *cond) β€” Unblock all threads currently blocked on the specified condition variable. Everybody up, it’s a broadcast. πŸ“’
  • int pthread_cond_destroy(pthread_cond_t *cond) β€” Destroy a condition variable. Condition variable: deleted. πŸ’€
  • int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) β€” Initialize a condition variable with specified attributes. Condition variable debut. πŸŽ€
  • int pthread_cond_signal(pthread_cond_t *cond) β€” Unblock at least one of the threads blocked on the specified condition variable. Wake at least one bestie. 🫢
  • int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) β€” Unlock the specified mutex, wait no longer than the specified time for a condition, and then relock the mutex. Unlock, wait with a time limit, relock. The full little routine. ⏳
  • int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *mutex) β€” Unlock the specified mutex, wait for a condition, and relock the mutex. Unlock, wait, relock. Periodt. πŸ’…

πŸ” Read/Write Lock Routines πŸ”

  • int pthread_rwlock_destroy(pthread_rwlock_t *lock) β€” Destroy a read/write lock object. RW lock: destroyed. 🧹
  • int pthread_rwlock_init(pthread_rwlock_t *lock, const pthread_rwlockattr_t *attr) β€” Initialize a read/write lock object. RW lock debut. ✨
  • int pthread_rwlock_rdlock(pthread_rwlock_t *lock) β€” Lock a read/write lock for reading, blocking until the lock can be acquired. Reading lock, and it will wait until it can get it. πŸ“–
  • int pthread_rwlock_tryrdlock(pthread_rwlock_t *lock) β€” Attempt to lock a read/write lock for reading, without blocking if the lock is unavailable. Try to read-lock, but no blocking if it’s unavailable. πŸ™…β€β™€οΈ
  • int pthread_rwlock_trywrlock(pthread_rwlock_t *lock) β€” Attempt to lock a read/write lock for writing, without blocking if the lock is unavailable. Try to write-lock, no blocking if it’s unavailable. ✍️
  • int pthread_rwlock_unlock(pthread_rwlock_t *lock) β€” Unlock a read/write lock. Unlocked, bestie. πŸ”“
  • int pthread_rwlock_wrlock(pthread_rwlock_t *lock) β€” Lock a read/write lock for writing, blocking until the lock can be acquired. Writing lock, and it will wait until it can get it. ✍️
  • int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr) β€” Destroy a read/write lock attribute object. RW lock attr: destroyed. 🧹
  • int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *pshared) β€” Retrieve the process shared setting for the read/write lock attribute object. Getting the process shared setting. 🫱
  • int pthread_rwlockattr_init(pthread_rwlockattr_t *attr) β€” Initialize a read/write lock attribute object. RW lock attr debut. ✨
  • int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared) β€” Set the process shared setting for the read/write lock attribute object. Process shared setting: set. πŸ’…

🧺 Per-Thread Context Routines 🧺

  • int pthread_key_create(pthread_key_t *key, void (*routine)(void *)) β€” Create a thread-specific data key. A key, just for your thread. πŸ”‘
  • int pthread_key_delete(pthread_key_t key) β€” Delete a thread-specific data key. Key deleted. πŸ—‘οΈ
  • void * pthread_getspecific(pthread_key_t key) β€” Get the thread-specific value for the specified key. Getting your thread-specific value. 🎁
  • int pthread_setspecific(pthread_key_t key, const void *value_ptr) β€” Set the thread-specific value for the specified key. Setting your thread-specific value. πŸ’…

🧼 Cleanup Routines 🧼

  • int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)) β€” Register fork handlers. Fork handlers: registered. 🍴
  • void pthread_cleanup_pop(int execute) β€” Remove the routine at the top of the calling thread’s cancellation cleanup stack and optionally invoke it. Pops the cleanup routine and can optionally invoke it. 🫧
  • void pthread_cleanup_push(void (*routine)(void *), void *routine_arg) β€” Push the specified cancellation cleanup handler onto the calling thread’s cancellation stack. Pushes a cleanup handler onto the calling thread’s cancellation stack. 🧚

πŸ’… IMPLEMENTATION NOTES (the tea β˜•)

Okay so real talk about how this actually works on your machine, bestie:

The current FreeBSD POSIX thread implementation is literally built into the 1:1 Threading Library, aka libthr, aka -lthr when you're linking. Iconic. ✨

It contains thread-safe versions of the Standard C Library (libc, -lc) functions and the thread functions, so you're not out here writing wrappers like a clown. 🫢

Threaded applications are linked with this library, periodt. So if your app is doing the multithreaded thing, that's the vibe you're linking against. 🧚


🌈 SEE ALSO (your reading list, bestie πŸ“š)

Like, go read these next, no cap β€” they're all (3) manpages and they're all gonna eat:

That's the whole squad, fr fr. πŸŽ€


πŸ‘‘ STANDARDS (the receipts 🧾)

So here's how you know who's official and who's just vibing:

The functions with the pthread_ prefix and not the _np suffix or the pthread_rwlock prefix conform to ISO/IEC 9945-1:1996 (β€œPOSIX.1”). Those are the certified good girls β€” fully standard, fully iconic. ✨

The functions with the pthread_ prefix and the _np suffix are non-portable extensions to POSIX threads. _np literally stands for "not portable," so like… don't be shocked when they don't exist everywhere, babe. πŸ™ˆ

The functions with the pthread_rwlock prefix are extensions created by The Open Group as part of the Version 2 of the Single UNIX Specification (β€œSUSv2”). Fancy committee energy, but we respect it. πŸ’œ


πŸ’€ tiny reminder bestie: _np = not portable. If you ship it, that's a choice, and the consequences are yours. Slay responsibly.

And that's the whole page, periodt! πŸ“ This one's from the Debian crew, dated October 12, 2021, and it's the PTHREAD(3) page β€” go forth and thread safely, my love. πŸ¦‹πŸ’–

πŸ“¦ where this page comes from