Multi-thread programming for APUE Learning (3): thread attributes, synchronization attributes, and apue multi-thread programming
I. The thread attributes can be modified using the pthread_attr_t structure, and these attributes are used to practice with the created thread. You can use the pthread_att_init function to initialize the pthread_attr_t structure and call pthread_attr_init, the pthread_attr_t structure contains the default values of all thread attributes supported by the operating system. Pthread_attr_destroy is used to destroy attribute objects and release resources.
#include <pthread.h>int pthread_attr_init(pthread_attr_t *attr)int pthread_attr_destroy(pthread_attr_t *attr)
There are four thread attributes:
1. detachstate attributes of a thread. guardsize the alert buffer size (number of bytes) at the end of the thread stack 3. the lowest address of the stackaddr thread stack 4. the minimum length of the stacksize thread stack. If you know that you do not need to know the thread termination status when creating a thread, you can modify the detachstate attribute in the pthread_attr_t structure so that the thread is separated from the beginning. You can use pthread_attr_setdetachstate to set the thread attribute detachstate to one of the following valid values: PTHREAD_CREATE_DETACHED, PTHREAD_CREATE_JOINABLE.
#include <pthread.h>int pthread_attr_getdetachstate(const pthread_attr_t *restrict attr, int *detachstate);int pthread_attr_setdetachstate(const pthread_attr_t *attr, int *detachstate);
Example:
# Include "apue. h "# include <pthread. h> int makethread (void * (* fn) (void *), void * arg) {int err; pthread_t tid; pthread_attr_t attr; err = pthread_attr_init (& attr ); if (err! = 0) {return err;} err = pthread_attr_setdetachstate (& attr, PTHREAD_CREATE_DETACHED); if (err = 0) {err = pthread_create (& tid, & attr, fn, arg);} pthread_attr_destroy (& attr); return err ;}View Code follows the POSIX standard and does not necessarily support thread stack attributes. You can use the _ POSIX_THREAD_ATTR_STACKADDR and _ POSIX_THREAD_ATTR_STACKSIZE symbols during compilation to check whether the system supports thread stack attributes. You can use pthread_attr_getstack and pthread_attr_setstack to manage the thread stack attributes.
#include <pthread.h>int pthread_attr_getstack(const pthread_attr_t *restrict attr, void **restrick stackaddr, size_t *restrict stacksize)int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize)
If the virtual address space of the thread stack is used up, you can use malloc or mmap to allocate space for the alternative stack. stackaddr is the lowest memory address of the stack.
You can also use pthread_attr_getstacksize and pthread_attr_setstacksize to read or set the thread attribute stacksize.
#include <pthread.h>int pthread_attr_getstacksize(const pthread_attr_t *restrict attr, size_t *restrict stacksize)int pthread_attr_setstacksize(pthread_attr_t *attr, size_t *stacksize)
The thread attribute guardsize controls the size of extended memory after the end of the thread stack to avoid stack overflow.
#include <phtread.h>int pthread_attr_getguardsize(const pthread_attr_t *restrict attr, size_t *restrict guardsize)int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
Ii. mutex attributes
Corresponding to non-default properties, you can use pthread_mutexattr_init to initialize and pthread_mutexattr_destroy to reverse initialize.
#include <pthread.h>int pthread_mutexattr_init(pthread_mutexattr *attr)int pthread_mutexattr_destroy(pthread_mutexattr *attr)
Two notable attributes in mutex attributes: process sharing attributes and type attributes
When the process sharing attribute is set to PTHREAD_PROCESS_SHARED, multiple processes are allowed to access the shared data. If the process sharing attribute is PTHREAD_PROCESS_PRIVATE, no.
#include <pthread.h>int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr, int *restrict pshared)int pthread_mutexattr_setpshared(const pthread_muteattr_t *attr, int pshared)
The Type attribute controls the lock feature of mutex. It is worth noting that the PTHREAD_MUTEX_RECURSIVE type allows the same thread to lock the mutex multiple times before unlocking the mutex. Recursive mutex maintains the base of the lock. The lock is not unlocked when the number of locks is different from the number of locks.
#include <pthread.h>int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restrict type)int pthread_mutexattr_settype(pthread_mutexattr *attr, int type)
Iii. read/write lock attributes
Use pthread_rwlockattr_init to initialize the pthread_rwlockattr_t structure and use pthread_rwlockattr_destroy to destroy the structure.
#include <pthread.h>int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
The unique attribute of the read/write lock is the process sharing attribute, which is the same as the process sharing attribute of the mutex.
#include <pthread.h>int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr, int *restrict pshared)int pthread_rwlockattr_setpshared(const pthread_rwlockattr_t *attr, int * pshared)
Iv. Condition variable attributes
There is a pair of functions for initialization and destruction.
#include <pthread.h>int pthread_condattr_init(pthread_condattr_t *attr)int pthread_condattr_destroy(pthread_condattr_t *attr)
Conditional variables support process sharing and clock attributes. process sharing attributes are the same as those of mutex processes.
#include <pthread.h>int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared)int pthread_condattr_setpshared(const pthread_condattr_t *attr, int pshared)
The clock attribute controls the time-out parameter of the pthread_cond_timedwait function, which clock is used by tsptr.
#include <pthread.h>int pthread_condattr_getclock(const pthread_condattr_t *restrict attr, clockid_t *restrict clock_id)int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id)