UNIX- thread (lower) thread control

 

UNIX Programming Chapter 12

12.2 thread limit

UNIX-related operating restrictions thread:

Limits Name ---- ---- name parameter description

PTHREAD_DESTRUCTOR_ITERATORS ---- Operating System to achieve the maximum number of attempts to destroy thread-specific data ----_ SC_THREAD_DESTRUCTOR_ITERATIONS a thread exits

The maximum number of keys PTHREAD_KEYS_MAX ---- process can create ----_ SC_THREAD_KEYS_MAX

---- PTHREAD_STACK_MIN a minimum number of bytes available thread stack ----_ SC_THREAD_STACK_MIN

The maximum number of threads PTHREAD_THREADS_MAX ---- process can create ----_ SC_THREAD_THREADS_MAX

Where name parameter is used to query function sysconf

 

12.3 Thread Attributes

pthread interfaces for threads and synchronization objects pattern property management:

- the type of each object with its own properties associated with objects (threads associated with the thread attributes associated with the mutex mutex attributes, etc.). A property of an object can represent multiple attributes. It provides functions to manage the properties of the object.

- there is an initialization function, the attribute set to the default values.

- There is also a function of the object's properties destroyed. If the initialization function allocates resources associated with the property object destructor is responsible for freeing these resources.

- Each attribute has a function of acquiring an attribute value from the attribute object. Because when the function returns 0 success, failure error number is returned, it is possible in the memory cell by a certain function parameters specified in the attribute value is returned to the caller attribute value is stored.

- Each attribute has an attribute value setting function. In this case, the attribute values ​​as parameters passed by value.

 

Function may be used to initialize pthread_attr_t pthread_attr_init structure. After calling pthread_attr_init, the default value is the operating system implementation supports all threads attributes pthread_attr_t structure contains.

#include<pthread.h>

int pthread_attr_init( pthread_attr_t *attr);

int pthread_attr_destroy( pthread_attr_t *attr);

  Two function's return value: If successful, returns 0; otherwise it returns an error number;

pthread_attr_destroy uninitialized function, if the memory space to achieve pthread_attr_init object's properties are dynamically allocated, pthread_attr_destroy will release the memory space. In addition, pthread_attr_destroy also initializes the value of a property of the object is invalid, and therefore, if the attribute of the object is misused, resulting in pthread_create function will return an error code.

 

Thread attributes:

Name --- Description

Separate state detachstate --- thread

Alert buffer size guardsize --- the end of the thread stack (in bytes)

stackaddr --- minimum thread stack address

--- STACKSIZE thread stack of the minimum length (in bytes)

 

If you are not interested in the current state of the termination of a thread, you can use pthread_detach function allows the operator to recover the system resources that it holds in the thread exits.

If a thread is created to know without knowing termination state of the thread, you can modify the properties pthread_attr_t detachstate thread structure, so that the thread start in a separated state. Pthread_attr_setdetachstate function may be used provided the thread attribute detachstate one of two legal values: PTHREAD_CREATE_DETACHED, in a separated state start thread; or to PTHREAD_CREATE_JOINABLE, normal start thread, terminate the application can get the state of the thread.

#include<pthread.h>

int pthread_attr_getdetachstate( const pthread_attr_t *restrict attr, int *detachstate);

int pthread_attr_setdetachstate( pthread_attr_t *attr, int *detachstate);

  Two function's return value: If successful, returns 0; otherwise it returns an error number;

Pthread_attr_getdetachstate can call the function to get the current thread detachstate property. The second parameter points or an integer provided PTHREAD_CREATE_DETACHED, or arranged PTHREAD_CREATE_JOINABLE, particularly depending on the property value given pthread_attr_t structure.

 

You can check whether the system supports the use of attributes for each thread _POSIX_THREAD_ATTR_STACKADDR and _POSIX_THREAD_ATTR_STACKSIZE symbol at compile time.

You can use the function pthread_attr_getstack and pthread_attr_setstack of thread stack property management.

#include<pthread.h>

int pthread_attr_getstack( const pthread_attr_t *restrict attr, void **restrict stackaddr, size_t *restrict stacksize);

int pthread_attr_setstack( pthread_attr_t *attr, void *stackaddr, size_t stacksize);

  Two function's return value: If successful, returns 0; otherwise it returns an error number;

stackaddr thread attribute is defined as the lowest stack memory address, but this is not necessarily the starting position of the stack. For a given processor architecture, if the stack is growing from higher addresses to lower addresses, then the property will be stackaddr thread end position of the stack, rather than start position.

Applications can also read or pthread_attr_getstacksize and functions provided pthread_attr_setstacksize thread attributes 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);

  Two function's return value: If successful, returns 0; otherwise it returns an error number;

If you want to change the default stack size, but do not want their own distribution processing thread stack, then use pthread_attr_setstacksize function is very useful. Stacksize setting properties, not be less than the selected stacksize PTHREAD_STACK_MIN.

After the end of the thread attributes guardsize control thread stack size to avoid stack overflow of extended memory. The attribute default value is defined by the specific implementation, but the common value is the system page size. Guardsize thread attributes can be set to 0, this feature does not allow attribute behavior occurs: in this case, does not provide a warning buffer. Similarly, if you modify the thread attributes stackaddr, the system will think that we will manage your own stack, and then alert the stack buffer mechanism is invalid, which is equivalent to the threads guardsize property is set to 0.

#include<pthread.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);

  Two function's return value: If successful, returns 0; otherwise it returns an error number;

If the attribute is modified guardsize thread, the operating system may put it takes an integer multiple of the page size. If the stack pointer to the thread overflow warning area, the application may be received by the error information signal.

 

12.4 Synchronization Properties

12.4.1 mutex attribute

Pthread_mutexattr_t mutex attribute is represented by the structure. For non-default properties, may be initializing pthread_mutexattr_t pthread_mutexattr_init structure, with pthread_mutexattr_destroy to uninitialized.

#include<pthread.h>

int pthread_mutexattr_init( pthread_mutexattr_t *attr);

int pthread_mutexattr_destroy( pthread_mutexattr_t *attr);

  Two function's return value: If successful, returns 0; otherwise it returns an error number.

pthread_mutexattr_init function with default attributes mutex initialization pthread_mutexattr_t structure. It is noteworthy that three properties are: the process of sharing property, as well as robust property type attribute.

In the process, multiple threads can access the same synchronization object. In this case, the process of sharing the mutex attribute should be set to PTHREAD_PROCESS_PRIVATE.

There is a mechanism: allows a plurality of independent processes mapped to the same memory block their separate address space. Like multiple threads access the same shared data, multiple processes often need access to shared data synchronization. If the mutex processes share attribute is set to PTHREAD_PROCESS_SHARED, mutex allocated blocks of a shared memory from among the plurality of processes in respect to each other may be used to synchronize these processes.

You can use the query function pthread_mutexattr_getpshared pthread_mutexattr_t structure, the process of getting it shared property, is the process of modifying a shared property with pthread_mutexattr_setpshared function.

#include<pthread.h>

int pthread_mutexattr_getpshared( const pthread_mutexattr_t *restrict attr, int *restrict pshared);

int pthread_mutexattr_setpshared( pthread_mutexattr_t *attr, int pshared);

  Two function's return value: return 0 if successful, otherwise an error number.

 

Robust mutex mutex attributes shared among multiple processes related. This means that, while holding the mutex process terminates, the need to address the mutex state recovery. In this case, the mutex is locked, it is difficult to recover. Other blocked in the lock of blocking the process will always go on.

Pthread_mutexattr_getrobust function may be used to obtain the value of the mutex robust property. Pthread_mutexattr_setrobust you can call the function to set the value of the mutex's robust attribute.

#include<pthread.h>

int pthread_mutexattr_getrobust( const pthread_mutexattr_t *restrict attr, int *restrict robust);

int pthread_mutexattr_setrobust( pthread_mutexattr_t *attr, int robust);

  Two function's return value: If successful, returns 0; otherwise, it returns an error number;

Robust property values ​​have two possible scenarios. The default value is PTHREAD_MUTEX_STALLED, you do not need to take special action when it means holding the mutex process terminates. In this case, the behavior is undefined after the mutex, waiting for the mutex unlock the application is effectively "pin down." Another value is PTHREAD_MUTEX_ROBUST, this value will result in the calling thread acquires the lock pthread_mutex_lock, while the lock is held by another process, but it does not terminate unlock the lock, then thread is blocked, the value returned from pthread_mutex_lock as EOWNERDEAD instead of 0. Applications can use this special return value is known, if possible (to protect the status and details of how to recover will vary depending on the application), regardless of their protected status mutex, need to be restored.

Use robust mutex changed the way we use pthread_mutex_lock, because now you must check three instead of two before the return value: no recovery success, we need to recover a success and failure. When not in use robust property, you can also check the success or failure.

 

If the application status can not be recovered at a later thread mutex unlock the mutex will be in permanent unavailable. To avoid such problems, the thread can call pthread_mutex_consistent function, indicates the state associated with the mutex before unlocking the mutex is consistent.

#include<pthread.h>

int pthread_mutex_consistent( pthread_mutex_t *mutex);

  Return Value: If successful, returns 0; otherwise it returns an error number;

If the thread does not have first call on pthread_mutex_consistent mutex was unlocked, the other trying to get the mutex blocked thread will get an error code ENOTERCONVERABLE. If this happens, the mutex is no longer available. Thread by calling in advance pthread_mutex_consistent, let mutex is working properly, so that it can continue to be used.

 

Mutex attribute type of locking feature. POSIX.1 defines four types:

Mutex -PTHREAD_MUTEX_NORMAL a standard type, without any special error checking or deadlock detection.

-PTHREAD_MUTEX_ERRORCHECK this type of mutex provides error checking.

-PTHREAD_MUTEX_RECURSIVE mutex type allows the same thread several times before locking the mutex mutex is unlocked. Recursive mutex lock maintenance count, in the number and unlock the lock times are not the same, it does not release the lock.

-PTHREAD_MUTEX_DEFAULT mutex type can provide a default characteristics and behavior. When the operating system to achieve this type it can be freely mapped to one other mutex types.

Pthread_mutexattr_gettype function can be obtained mutex type attribute, a type attribute modification mutex pthread_mutexattr_settype function.

#include<pthread.h>

int pthread_mutexattr_gettype( const pthread_mutexattr_t *restrict attr, int *restrict type);

int pthread_mutexattr_settype( pthread_mutexattr_t *attr, int type);

  Two function's return value: If successful, returns 0; otherwise it returns an error number;

 

Thread (on), he said that when using condition variables in the thread, you need to be mutex lock unlock protection. pthread_cond_wait and pthread_cond_timedwait function to release the mutex associated with the condition. At this time it is not suitable for use recursive mutex.

 

12.4.2 write lock attributes

Similar to the read-write lock a mutex, have attributes. Pthread_rwlockattr_init pthread_rwlockattr_t structure may be initialized with the initialization pthread_rwlockattr_destroy trans configuration.

#include<pthread.h>

int pthread_rwlockattr_init( pthread_rwlockattr_t *attr);

int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);

  Two function's return value: If successful, returns 0; otherwise, it returns an error number;

The only attribute is read-write locks support the process of sharing property.

#include<pthread.h>

int pthread_rwlockattr_getpshared( const pthread_rwlockattr_t *restrict attr, int *restrict pshared);

int pthread_rwlockattr_setpshared( pthread_rwlockattr_t *attr, int pshared);

  Two function's return value: If successful, returns 0; otherwise, it returns an error number;

 

12.4.3 condition variable attributes

Condition variable two properties: the process of sharing and clock properties.

#include<pthread.h>

int pthread_condattr_init( pthread_condattr_t *attr);

int pthread_condattr_destroy( pthread_condattr_t *attr);

  Two function's return value: If successful, returns 0; otherwise, it returns an error number;

Like other synchronization properties, condition variables to support the process of sharing property. It controls the condition variable can be used by multiple threads process sheets, or can be used by threaded multi-process.

#include<pthread.h>

int pthread_condattr_getpshared( const pthread_condattr_t *restrict attr, int *restrict pshared);

int pthread_condattr_setpshared( pthread_condattr_t *attr, int pshared);

  Two function's return value: If successful, returns 0; otherwise it returns an error code;

 

Clock control property used timeout parameter (tsptr) function is calculated pthread_cond_timedwait which clock. Function may be used pthread_condattr_getclock ID may be used to obtain the clock pthread_cond_timedwait function before use pthread_cond_timedwait function requires pthread_condattr_t condition variables initialized with the object. ID can be modified in pthread_condattr_setlock clock function.

#include<pthread.h>

int pthread_condattr_getlock( const pthread_condattr_t *restrict attr, clockid_t *restrict clock_id);

int pthread_condattr_setclock( pthread_condattr_t *attr, clockid_t clock_id);

  Two function's return value: If successful, returns 0; otherwise, it returns an error code;

 

Clock ID clockid_t desirable type:

Identifier --- Option --- Description

CLOCK_REALTIME ---- ---- real-time system

CLOCK_MONOTONIC ----_ POSIX_MONOTONIC_CLOCK ---- without real-time system of negative hops

CLOCK_PROCESS_CPUTIME_ID ----_ POSIX_CPUTIME calling process ---- CPU time

CLOCK_THREAD_CPUTIME_ID ----_ POSIX_THREAD_CPUTIME ---- calling thread CPU time

 

12.4.4 barrier properties

There barrier properties. Pthread_barrierattr_init barrier function may be used to initialize the object attribute, anti-initialize the object attribute with pthread_barrierattr_destroy barrier function.

#include<pthread.h>

int pthread_barrierattr_init( pthread_barrierattr_t *attr);

int pthread_barrierattr_destroy( pthread_barrierattr_t *attr);

  Two function's return value: If successful, returns 0; otherwise it returns an error number;

Currently the only barrier property defines the process of sharing property, which controls the barrier can be a thread using multiple processes, or can only be used by multiple threads within a process initialization barrier.

#include<pthread.h>

int pthread_barrierattr_getpshared( const pthread_barrierattr_t *restrict attr, int *restrict pshared);

int pthread_barrierattr_setpshared( pthread_barrierattr_t *attr, int pshared);

  Two function's return value: If successful, returns 0; otherwise it returns an error code.

The process of the implementation of shared values ​​can be PTHREAD_PROCESS_SHARED (multiple threads in multiple processes available), it can be PTHREAD_PROCESS_PRIVATE (only multiple threads within that process initialization barrier available).

 

12.5 reentrant

If a function can be safe to call multiple threads at the same point in time, the function is said to be thread-safe.

Support thread-safe function of the operating system implementation will be defined in <unistd.h> symbol _POSIX_THREAD_SAFE_FUNCTIONS. Applications can use the sysconf function parameter passing _SC_THREAD_SAFE_FUNCTIONS checks at run-time support thread-safe function.

If a function of multiple threads is reentrant, say that a function is thread-safe. But it does not explain a signal processing program for this function is reentrant. If the function of the asynchronous signal handler is safe re-entry, then it can be said that the function is an asynchronous signal safe.

 

12.6 Thread-Specific Data

 Thread-specific data (thread-specific data), also known as thread private data is stored and a mechanism to query a particular thread-related data. The reason we call this data is called thread-specific data or thread private data, we hope that each thread can access its own separate copy of the data without having to worry about synchronization issues with access to other threads.

Threading model to promote the sharing of data and process attributes, but still using thread-private data The second reason is: First, sometimes based on the need to maintain data for each thread, since the thread ID is small and does not guarantee consecutive integers , you can not simply assign a data array for each thread, with the thread ID as an index of the array. Even if the thread ID is indeed small, consecutive integers, we might also want to have some additional protection against data a thread confused with data from other threads. Second, it provides a process-based interface allows multi-threaded environment adaptation mechanisms. An obvious example is the errno value, in the process, errno process context is defined as an integer of globally accessible. System calls and library routines set errno when you call or fails, it results as a subsidiary operation failed. In order to make use of those original thread can also be process-based system calls and library routines, errno may be redefined as thread private data, so that a thread errno to do a reset operation does not affect the value of errno other threads in the process .

Although the underlying implementation can not prevent the threads can access the capacity of the entire address space, but the thread-specific data management functions can improve the independence of data between threads so that the thread is not easily accessible to other threads thread-specific data.

Before allocating thread specific data, we need to create the data associated with the key. This key will be used to gain access to the thread-specific data. Use pthread_key_create create a key.

#include<pthread.h>

int pthread_key_create(pthread_key_t *keyp, void (*destructor)( void *));

  Return Value: If successful, returns 0; otherwise it returns an error code;

Create a key stored in memory unit keyp points, this key can be used by all threads in the process used, but each thread to this key associated with a different thread-specific data addresses. When you create a new key, data address of each thread is set to null.

In addition to creating keys, pthread_key_create key that can be associated with a selectable destructor. When this thread exits, if the address data has been set to a non-null value, then the destructor is invoked, it is the only parameter data address. If the incoming destructor is empty, indicating that no destructors associated with the key. When a thread or a thread of execution calling pthread_exit return normal exit, the destructor will be called. Also, when thread cancellation, only after the last cleanup handler returns, the destructor will be called. If a thread calls exit, _exit, _Exit or abort, or other non-normal exit occurs, it does not call the destructor.

Thread commonly used malloc to allocate memory for thread-specific data. Typically destructor releases allocated memory. If the thread is not released before the memory is to quit, then this memory will be lost, that process thread belongs to a memory leak.

Thread can be assigned to a plurality of thread-specific data keys, each key can have a destructor function associated with it. The number of each operating system can achieve key process that can be allocated to restrict (PTHREAD_KEYS_MAX).

A thread exits, the destructor of the thread-specific data in accordance with the order defined in the operating system is invoked implemented. Destructor might call another function, which may create a new thread-specific data, and this data is associated with the current key. When all destructors are call is completed, the system checks to see if there is non-empty thread-specific data value associated with a key, if any, once again calling the destructor. This process will be repeated until all of the key threads are empty thread-specific data values, or the maximum number of attempts have been made in the PTHREAD_DESTRUCTOR_ITERATORS defined.

For all threads, we can cancel the association between keys and thread-specific data value by calling pthread_key_delete.

#include<pthread.h>

int pthread_key_delete( pthread_key_t key);

  Return Value: If successful, returns 0; otherwise it returns an error number.

Note that the call does not activate the pthread_key_delete destructor associated with the key. To release any thread-specific data value associated with the key memory, additional measures need to be taken in the application.

 

The need to ensure the distribution of keys and not due to competition in the initialization phase change occurs. Solve the competition is to use pthread_once.

#include<pthread.h>

pthread_once_t initflag = PTHREAD_ONCE_INIT;

int pthread_once( pthread_once_t *initflag, void (*initfn)(void));

  Return Value: If successful, returns 0; otherwise it returns an error number;

initflag must be a non-local variable (e.g., global or static variable), and must be initialized PTHREAD_ONCE_INIT.

If each thread calls pthread_once, the system can guarantee initialization routine initfn only be called once. That system when the first call pthread_once.

 

After the key is created, you can put keys and thread-specific data associated pthread_setspecific by calling the function. The address can be obtained through the thread-specific data pthread_getspecific function.

#include<pthread.h>

void *pthread_getspecific( pthread_key_t key);

  Return Value: thread-specific data value; if no value associated with the key, returns NULL.

int pthread_setspecific( pthread_key_t key, const void *value);

  Return Value: If successful, returns 0; otherwise it returns an error number.

If there is no thread-specific data value associated with a key, pthread_getspecific returns a null pointer, we can use this return value to determine whether to call pthread_setspecific.

 

12.7 Cancel options

Two threads not included in the attribute pthread_attr_t structure, they are canceled and the cancel state type. These two properties influence the behavior of threads in response to a function call pthread_cancel presented.

To cancel the state property may be PTHREAD_CANCEL_ENABLE, it can also be PTHREAD_CANCEL_DISABLE. Thread can modify it to cancel the state by calling pthread_setcancelstate.

#include<pthread.h>

int pthread_setcancelstate( int state, int *oldstate);

  Return Value: If successful, returns 0; otherwise it returns an error number;

pthread_setcancelstate cancel the current state is set to State, cancel the original state is stored in the memory cell pointed to by the oldstate, which is a two-step atomic operation.

pthread_cancel call does not wait for the thread to terminate (a request to cancel a thread). By default, threads or continue to run after the cancellation request is issued, until the thread reaches a cancellation point. Thread cancellation point is a position to check whether it has been canceled, if canceled, in accordance with the request to act.

The default state is canceled when the thread starts PTHREAD_CANCEL_ENABLE. When the state is set to PTHREAD_CANCEL_DISABLE, calls to pthread_cancel and will not kill the process. In contrast, a cancellation request for this thread is still in a suspended state, when the state again becomes PTHREAD_CANCEL_ENABLE canceled, the next thread to cancel a point process all pending cancellation request.

You can also call the function to add your own pthread_testcancel cancellation point in the program.

#include<pthread.h>

void pthread_testcancel( void);

When you call pthread_testcancel, if there is a cancellation request is pending, and canceled and is not set to be invalid, then the thread will be canceled. However, if the cancellation is deactivated, pthread_testcancel call will have no effect.

 

The default cancellation type we have described, also known as deferred canceled. After calling pthread_cancel, before the thread reaches a cancellation point, not a real cancellation occurs. You can be modified by a call to cancel pthread_setcanceltype.

#include<pthread.h>

int pthread_setcanceltype( int type, int *oldtype);

  Return Value: If successful, returns 0; otherwise it returns an error number;

pthread_setcanceltype cancellation type is set to the function type (type parameter may be PTHREAD_CANCEL_DEFERRED, may be PTHREAD_CANCEL_ASYNCHRONOUS), the return to the original cancellation type integer unit oldtype points.

Asynchronous cancel and postpone cancel different, because when using asynchronous canceled, the thread can be revoked at any time, not have to meet in order to cancel the cancellation point.

 

12.8 threads and signals

Each thread has its own signal mask character, but the processing of the signal is shared by all threads in the process.

Signal process is delivered to a single thread. If a signal related to a hardware failure, then the signal will normally be delivered to cause the thread to the event, while others were sent to signal to any one thread.

Pthread_sigmask threads to modify the mask word.

#include<pthread.h>

int pthread_sigmask( int how, const sigset_t *restrict set, sigset_t *restrict pset);

  Return Value: If successful, returns 0; otherwise it returns an error number;

pthread_sigmask work in the thread, and returns an error code on failure, no longer as set errno as sigpromask and returns -1. set parameter comprises a set of threads used to modify the signal word signal shielding. how the parameter can take one of three values: SIG_BLOCK, the addition of a signal set to the thread shield signal word; SIG_SETMASK, signaling set jacquard thread mask word; SIG_UNBLOCK, the shield is removed from the thread set signal word. If the parameter is not oset mask character signal before empty, the thread is stored in its configuration sigset_t pointed. Parameter can be set by the thread is set to NULL, and the parameter set to the address oset sigset_t structure, to obtain the current signal mask character.

 

Thread can wait for one or more signals occur by calling sigwait:

#include<pthread.h>

int sigwait( const sigset_t *restrict set, int *restrict signo);

  Return Value: If successful, returns 0; otherwise it returns an error number;

set parameter specifies a set of signal waiting threads. Return, signo including integer number of points of the transmission signal.

If a signal is concentrated in a suspended state when sigwait call, then sigwait will return without blocking. Before returning, sigwait removed from the process those signals in a suspended state of waiting. If the concrete implementation supports multiple instances of the signal and the signal line is suspended, then the sigwait will remove an instance of the signal, other instances will continue to line up.

In order to avoid wrong behavior occurs, the thread before calling sigwait, it must block those signals is waiting. sigwait function unblocked state signal set atomically, until a new signal is delivered. Before returning, sigwait restore signal shielding the word thread.

The advantage of using sigwait function is that it simplifies signal processing, allowing a signal generated asynchronously processing synchronous manner. In order to prevent the signal interruption thread can mask character signal to the signal in each thread. You can then arrange a dedicated thread processing signals. These can be dedicated thread function calls, do not worry about what function is safe to call the signal handler, because these function calls from a normal thread context, rather than the traditional signal handler interrupts the normal execution of threads.

If multiple threads waiting for a signal blocked in the same call sigwait in, so when the signal delivery, only one thread can return from sigwait in. If a signal is caught, and a thread is waiting for the call to the same signal sigwait, then the time will be the operating system implementation to decide on ways to deliver signals. Operating system implementation allows sigwait return, can also activate a signal handler, but the two situations do not occur simultaneously.

Should send a signal to the thread, you can call pthread_kill.

#include<pthread.h>

int pthread_kill( pthread_t thread, int signo);

  Return Value: If successful, returns 0; otherwise it returns an error number.

Signo you can pass a value of 0 to check whether there is a thread. If the default signal processing operation is to terminate the process, then passes the signal to a thread will still kill the whole process.

Note that the alarm clock timer is a process resource, and all threads share the same clock. (Alarm set an alarm time value for the process, when you call again, this value will update process)

 

12.9 thread and fork

When a thread calls fork, to create a copy of the entire process address space for the child process.

Child process through inheritance copy of the entire address space, also inherited the status of each mutex, read-write locks, and condition variables from the parent process there. If the parent process contains more than one thread in the child process after fork return, if not immediately, then immediately calls exec, you need to clean up the lock state.

Within the child process, there is only one thread that is a copy of the thread fork called by the parent process constituted. If the parent process thread owns the lock, the child will occupy the same lock. The problem is that a copy of the thread of the child process does not include possession of the lock, so there is no way the child until it took possession of what lock, which locks to be released.

If the child process calls one of the exec function returns immediately from after the fork, you can avoid such problems. In this case, the old address space is discarded, so the state of the lock does not matter. However, if the child needs to continue processing the case, this strategy will not work, you also need to use other strategies.

In a multithreaded process, in order to avoid an inconsistent state problems, POSIX.1 statement, fork and return to the child process calls between one of the exec function, the child process can only be called an asynchronous signal safe function. This limits what the child can do before calling exec, but does not involve the child in the locked state of the problem.

To clear the lock state can be established by calling pthread_atfork fork handler function.

#include<pthread.h>

int pthread_atfork( void (*prepare)(void), void (*parent)(void), void (*child)(void) );

  Return Value: If successful, returns 0; otherwise an error number;

You can install up to three to help clean up the lock function with pthread_atfork function. prepare fork handler by the parent process before the child process calls fork to create. This task fork handler is defined in the parent process to obtain all locks. parent fork after fork handler is to create a child process, the parent process before returning to the calling context. This task fork handlers are locks on all prepare fork handler acquired unlock. child fork handler called in the context of the child before the fork return. Like the parent fork handler, child fork handler must also prepare fork handler gets release all the locks.

 

12.10 threads and I / O

When pread and pwrite good use in a multi-threaded environment, because the first call lseek then call the read / write, as this two-step is not atomic, synchronous insecurity occurs when multiple threads at the same time it calls operations of the same file (because the process a file descriptor has only one entry offset).

 

Guess you like

Origin www.cnblogs.com/cjj-ggboy/p/12327186.html