Transferred from http://blog.csdn.net/zsf8701/article/details/7842392
The thread properties are structured as follows:
typedef struct
{
int etachstate; Detach State of Thread
int schedpolicy; Thread Scheduling Policy
Structsched_param Schedparam; Scheduling Parameters for Threads
int inheritsched; Inheritance of threads
int scope; Scope of threads
size_t Guardsize; Alert buffer size at end of thread stack
int stackaddr_set; Stack settings for threads
void* stackaddr; Position of line stacks
size_t stacksize; The size of the line stacks
}pthread_attr_t;
The property value cannot be set directly, it must be manipulated using the correlation function, and the function initialized is Pthread_attr_init, which has to be called before the Pthread_create function. You must then use the Pthread_attr_destroy function to release resources. Threading properties mainly include the following properties: Scope (scope), stack size (stack size), stack address (stack addressing), priority (priority), detached state (detached states), scheduling policies, and parameters (scheduling Policy and parameters). The default properties are unbound, detached, stack of the default 1M, and the same level of precedence as the parent process. I. Scope of the thread (scope)
Scope properties describe which threads a particular thread will compete with for resources. A thread can compete for resources within two competing domains: Process scope: With other threads within the same process. System domain: With all threads in the system. A thread with a system domain will compete with all the system domain threads in the system to prioritize the processor resources for scheduling. Solaris systems, in fact, starting with the Solaris 9 release, the system no longer distinguishes between these two scopes. Second, the binding state of the thread (binding states)
Light processes (lwp:light Weight process) The binding of threads involves another concept: light processes (lwp:light Weight process): A lightweight process can be understood as a kernel thread, located between the user layer and the system layer. The system's allocation of thread resources and control of threads is achieved through a light process, and a lightweight process can control one or more threads. Non-binding state
By default, how many light processes to start, and which light processes to control which threads are controlled by the system, is called Unbound. Binding status
binding, the name implies that a thread is fixed to "bind" on a light process. The bound thread has a higher response speed because the scheduling of the CPU time slice is oriented toward the light process, and the bound thread guarantees that it always has a light process available when needed. By setting the priority and dispatch level of the bound light process, the bound thread satisfies the requirements such as real-time response.third, the separation state of the thread (detached states)The separation state of a thread determines how a thread terminates itself. Non-detached state
The default property of a thread is a detached state, in which case the original thread waits for the thread to be created to end. The created thread is terminated only when the Pthread_join () function returns, in order to release the system resources it occupies. Detach State
The detach thread is not waiting for another thread, the end of its own run, the thread is terminated, immediately release the system resources. You should choose the appropriate separation state according to your own needs. The function of the thread detach State: Pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate).
The second parameter can be selected as pthread_create_detached (Detach thread) and PTHREAD _create_joinable (non-detached threads).
One thing to note here is that if you set a thread to detach, and the thread runs very fast, it is likely to terminate before the Pthread_create function returns, and it may be possible to hand over the thread number and system resources to another thread after it terminates, calling Pthread_ The create thread gets the wrong thread number. One of the easiest ways to avoid this situation is to take a certain synchronization action, in which you can call the Pthread_cond_timewait function in the thread being created, and let the thread wait for a while, leaving enough time for the function pthread_create to return. Setting a wait time is a common method in multithreaded programming. But be careful not to use functions such as wait (), which is to make the whole process sleep and not solve the problem of thread synchronization. You can also use the Pthread_detach function to set the detach thread (the child thread Pthread_detach (pthread_self ()) or the parent thread call Pthread_detach (thread_id) (non-blocking, can return immediately)Iv. Thread Priority (priority)The new thread has a default priority of 0. The new thread does not inherit the parent thread dispatch priority (pthread_explicit_sched) is valid only if the dispatch policy is in real time (i.e. SCHED_RR or SCHED_FIFO) and can be passed at run time by Pthread_setschedparam () function to change, the default is 0.
Five, the thread's stack address (stack addresses)POSIX.1 defines two constants _posix_thread_attr_stackaddr and _posix_thread_attr_stacksize whether the stack properties are supported by the detection system. You can also pass _SC_THREAD_ATTR_STACKADDR or _sc_thread_attr_stacksize to the sysconf function for detection. When the process stack address space is not sufficient, the specified new thread uses the space allocated by malloc as its own stack space. The stack address of the thread is set and obtained by PTHREAD_ATTR_SETSTACKADDR and pthread_attr_getstackaddr two functions respectively. The address passed to the PTHREAD_ATTR_SETSTACKADDR function is the low address of the buffer (not necessarily the starting address of the stack, which may grow from a high address to a low address).the stack size of the thread ( stack size)When there are many threads in the system, it may be necessary to reduce the default size of each line stacks and prevent the process from having enough address space when the function called by the thread allocates a large local variable or the function call is deep, you may need to increase the default size of the line stacks. Functions Pthread_attr_getstacksize and Pthread_attr_setstacksize provide settings.seven, the thread stack protected area size (stack guard size)The online stacks top leaves a space to prevent stack overflow. When the stack pointer enters the protected area, the system emits an error, usually sending a signal to the thread. The default value for this property is the pagesize size, which is automatically padded to the size of the page as an integer when the property is set. When the stack address attribute is changed, the stack protected area is usually zero-clear.viii. Thread Scheduling strategy (Schedpolicy)
The POSIX standard specifies three scheduling policies: first-in-First out policies (SCHED_FIFO), circular policies (SCHED_RR), and custom Policies (Sched_other). Sched_fifo is a queue based scheduler that uses a different queue for each priority. SCHED_RR are similar to FIFO, but each thread of the former has an execution time quota. Sched_fifo and SCHED_RR are extensions to POSIX realtime. Sched_other is the default scheduling policy. The new thread uses the Sched_other scheduling policy by default. Once the thread starts to run, it is preempted until the thread is blocked or stopped. Sched_fifo
If the calling process has a valid user ID 0, contention for System (Pthread_scope_system) first-in-first-pass belongs to the real-time (RT) scheduling class. If these threads are not preempted by a higher-priority thread, the thread continues to process until the thread is discarded or blocked. For a thread that has a process contention scope (pthread_scope_process) or whose calling process does not have a valid user ID 0, use Sched_fifo,sched_fifo based on the TS scheduling class. Sched_rr
If the calling process has a valid user ID 0, a loop thread that is contention for system (Pthread_scope_system) is a real-time (RT) dispatch class. If these threads are not preempted by higher priority threads, and those threads are not discarded or blocked, they will be executed throughout the time period determined by the system. For threads that have process contention scopes (pthread_scope_process), use SCHED_RR (based on the TS scheduling class). In addition, the calling process for these threads does not have a valid user ID of 0. ix. thread parallel level (concurrency)----not clear.
The application uses Pthread_setconcurrency () to notify the system of the required concurrency level.
Transferred from http://blog.csdn.net/cywosp/article/details/26469435
Initialization of 二、一次Let's take a look at a one-time initialization before the Chengte of the tutorial line is available. multithreaded programs sometimes have the requirement that, regardless of how many threads are created, initialization of some data can occur only once. Columns such as: in a C + + program, a class in the entire process life cycle can only exist one instance object, in the case of multithreading, in order to enable the object to be safe initialization, one-time initialization mechanism is particularly important. This implementation is often referred to as a single case pattern (Singleton) in design patterns. The following functions are provided in Linux to enable one-time initialization: #include <pthread.h>
Returns 0 on success, or a positive error number on Error int pthread_once (pthread_once_t *once_control, void (*init) (void)); With the state of the parameter Once_control, the function pthread_once () ensures that no matter how many times the thread calls the function, only the function defined by the caller that Init points to is executed once. The function that init points to does not have any arguments in the form of: void init (void) {//Some variables initializtion in-here} and parameter Once_control must be a pthread_once_t class A pointer to a type variable that points to a static variable initialized to Pthrad_once_init. A function std::call_once () that provides similar functionality after c++0x is similar to this function. Use an instance to refer to the HTTPS://GITHUB.COM/APUSAPP/SWIFT/BLOB/MASTER/SWIFT/BASE/SINGLETON.HPP implementation.
third, the thread local data APIThe following functions are provided in Linux to manipulate thread-local data #include <pthread.h>
Returns 0 on success, or a positive error number on Error int pthread_key_create (pthread_key_t *key, void (*destructor ) (void *));//Bestin thepthread_once inside Call, returns a global key that is shared with all threads. In this way, this key is only created once in multithreading
Returns 0 on success, or a positive error number on Error int pthread_key_delete (pthread_key_t key);
Returns 0 on success, or a positive error number on Error int pthread_setspecific (pthread_key_t key, const void *value );
Returns pointer, or NULL if no thread-specific data is associated with key void *pthread_getspecific (pthread_key_t key );
The function pthread_key_create () Creates a new key for thread-local data and points to the newly created key buffer via key. Because all threads can use the new key that is returned, the parameter key can be a global variable (generally not using global variables in C + + multithreaded programming, but instead using separate classes to encapsulate thread-local data, each variable using a separate pthread_key_t). destructor refers to a custom function that is formatted as follows: void Dest (void *value) {//Release storage pointed to ' value '} The value associated with the key is not n as long as the thread terminates Ull, the function referred to by destructor will be invoked automatically. If there is more than one thread in a thread that stores variables locally, then the order of invocation of the destructor function for each variable is indeterminate, so the design of the destructor function for each variable should be independent of each other.
The function pthread_key_delete () does not check whether the thread is currently using the threaded local data variable, nor does it call the cleanup function destructor, but simply releases it for use by the next call to Pthread_key_create (). In a Linux thread, it also sets the thread data entry associated with it to null. Because the system has limits on the number of pthread_key_t types in each process, infinite pthread_key_t variables are not created in the process. Linux can determine the maximum number of keys that the current system supports by Pthread_key_max (defined in limits.h files) or system call sysconf (_sc_thread_keys_max). Linux defaults to 1024 keys, which is sufficient for most programs. If you have more than one thread in a thread that stores variables locally, you can typically encapsulate them into a data structure and then associate the encapsulated data structure with a thread-local variable, which reduces the use of key values.
The function pthread_setspecific () is used to store a copy of value in a data structure and associate it with the calling thread and key. Parameter value usually points to a piece of memory allocated by the caller, which is passed as a parameter to the destructor function associated with the key when the thread terminates. When a thread is created, all thread-local storage variables are initialized to NULL, so the pthread_getspecific () function must first be called to confirm that the corresponding key is already associated, if not, then the first time such a variable is used Pthread_ Getspecific () Allocates a piece of memory and holds a pointer to the memory block through the pthread_setspecific () function. The value of the parameter value can also be not a memory area that points to the caller's allocation, but rather any variable value that can be cast to void*, in which case the previous pthread_key_create () function should set the parameter destructor to null The function pthread_getspecific () is just the opposite of Pthread_setspecific (), which takes the value of the pthread_setspecific () setting out. It is best to convert void* to a pointer to the original data type before using the fetched value.Iv. deep understanding of thread-local storage mechanism1. An in-depth understanding of the implementation of thread-local storage facilitates the use of its APIs. The following arrays are included in a typical implementation: a global (process-level) array that holds the key-value information for thread-local storage pthread_key_create () returns the pthread_key_t type value that is the index of the global array, which is marked as Pthread_ Keys, the format of which is probably as follows:
Each element of an array is a structure that contains two fields, the first field marks whether the array element is in use, and the second field is used to hold a copy of the destructor for this key, thread-local storage change, the destructor function. Each thread also contains an array of pointers that are allocated for each thread Chengte a pointer to a data block (by calling the Pthread_setspecific () function to store the pointer, that is, value in the parameter) 2. In the implementation of the common storage pthread_setspecific () function parameter value, most of them are similar to the implementation of the following diagram. The diagram assumes that pthread_keys[1] is assigned to the FUNC1 () function, and the Pthread API maintains a pointer array for each function that points to a thread-local-storage block, where each array element is the global pthread_ in the implementation of the diagram thread Local Data key (above) Element one by one in the keys corresponds.
v. Summarizing the use of global variables or static variables is a common cause of non thread-safe programming for multithreading. In multithreaded programs, one of the common ways to protect against thread security is to use mutexes for protection, which brings concurrent performance degradation and only one thread can read and write data. If you can avoid using global variables or static variables in your programs, these programs are thread-safe and performance can be greatly improved. If some data can only be accessed by one thread, this type of data can be handled using a thread-local storage mechanism, although the use of this mechanism will have a certain impact on the efficiency of program execution, but these performance impacts will be negligible for the use of lock mechanisms. Linux C + + thread-local storage simple implementation can refer to https://github.com/ApusApp/Swift/blob/master/swift/base/ Threadlocal.h, a more detailed and efficient implementation can refer to the threadlocal implementation in Facebook's Folly Library. A more high-performance thread-local storage mechanism is the use of __thread, which is discussed in the next section. --------------------------------------------------------------------------------
Reprint please explain source: http://blog.csdn.net/cywosp/article/details/26876231
thread-local storage in Linux (ii)
There is also a more efficient method of thread-local storage in Linux, which is to define variables using keyword __thread. __thread is a built-in thread-local storage facility for GCC (thread-local Storage), which is highly efficient and faster than pthread_key_t, with storage performance comparable to global variables and simpler to use. Creating a thread local variable simply adds a __thread description to the declaration of the global or static variable. Columns such as: static __thread char t_buf[32] = {' n '}; extern __thread int t_val = 0; With __thread variables, each thread has a copy of the variable and does not interfere with each other. A variable in the thread-local store persists until the thread terminates and automatically releases the store when the thread terminates. __thread is not available for all data types because it supports only the pod (Plain old data structure) [1] type and does not support class types-it cannot automatically invoke constructors and destructors. At the same time, __thread can be used to decorate global variables, static variables within functions, but not to modify local variables of functions or normal member variables of class. In addition, initialization of __thread variables can only be done with compile-time constants, such as: __thread std::string t_object_1 ("Swift"); //error because the constructor of the object cannot be invoked __thread std::string * T_object_2 = new std::string (); //error, initialization must be of compile-time constants __thread std::string* t_object_3 Nbsp;nullptr; //correct butis to manually initialize and destroy objects
In addition to the above, there are several points to note about the declaration and use of thread-local storage variables: If the usage keyword is static or extern in the variable declaration, then the keyword __thread must follow. As with general global variables or static variables, a thread local variable can set an initialization value when declared.