Summary: multi-threaded APIs in Linux (POSIX Threads)

Source: Internet
Author: User

 

POSIX thread:

A completed thread/process consists of three parts: code + Data + Memory stack. When a sub-thread and sub-process are created,

For fork () to create a sub-process, make a copy of all three parts, including the file descriptor, virtual memory, and the sub-process to close the file descriptor will not affect the descriptor in the parent process;

When pthread_create () is used to create a sub-thread, only the memory stack is copied, and other parts (code and data are shared). If a thread changes the value of a variable, all other threads call the changed value;

Header file # include <pthread. h>

Compilation parameters:-lpthread

 

 

(1) involved types:

Pthread_t, pthread_attr_t, pthread_cond_t, pthread_mutexattr_t, void * (*) (void *),

 

(2) involved functions:

 

Pthread_cancel, pthread_wait,

Pthread_create, pthread_self, pthread_detach, pthread_join, pthread_exit,

Pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock, pthread_mutex_destory; // All parameters are pthread_mutex_t *

Int pthread_attr_init (pthread_attr_t *), int pthread_attr_destory (pthread_attr_t *),

Int pthread_attr_setdetachstatus (pthread_attr_t *, INT); // set attributes

Int pthread_attr_getdetacstatus (const pthread_attr_t *, int *); // get attributes

Pthread_cond_wait, pthread_cond_timewait, pthread_cond_signal, pthread_cond_broadcast, pthread_cond_destory;

 

1. Set thread attributes:

A thread attribute object (such as pthread_attr_t attr_test) can be used to create multiple threads. It is unnecessary to keep this object after the thread is created;

Among all the attributes of a thread, the most important thing is the detach status. A thread can be a waiting thread or a detach thread ), the default value is joinable thread;

For a non-detached joinable thread, similar to the zombies process in the process, after joinbale thread exits, the resource will not be released immediately until it is returned by thread_join;

When a detach thread exits, the resource is immediately released, and other threads cannot learn the returned value;

Code example in the main thread:

 

Pthread_attr_t ATTR; // (1) create a variable:

Phtread_attr_init (& ATTR); // (2) initialize this property variable;

Pthread_setdetachstatus (& ATTR, pthread_created_detached); // (3)

Pthread_create (& T, & ATTR, & function, null); // (4) create a thread;

Pthread_destory (& ATTR); // (5) after creation, the property variable can be destroyed;

Pthread_join (T, null); // error! The separated thread cannot be joined.

Return; // The main thread ends.

 

2. Create thread:

Int pthread_create (pthread * thread, pthread_attr_t * ATTR, void * (* start_routine) (* void), void * Arg );

Pthread_attr_t * and void * Arg can be set to null;

 

3. Get the PID of the thread:

Pthread_t pthread_self (void );

 

4. Thread separation:

Int pthread_detach (pthread_t thread );

The thread is set to separate. When this thread exits, it will not pass the return value to any other thread, and the separated thread cannot be pthread_join ();

For example, to separate threads:

Void * mythread (void * PARAM)

{

Pthread_detach (pthread_self ());

Pthread_exit (PARAM );

}

 

5. Thread wait (ADD ):

Pthread_join (pthread thread, void ** status );

The main creates n threads. It cannot be determined that the main must exit after all threads exit. Therefore, let the main thread wait until all the sub-threads exit before exiting;

The caller can exit only after the thread identified by the first parameter exits. The second parameter stores the return value of the function;

 

 6. Exit and cancel the thread:

Int pthread_exit (void * retval );

Calls within the thread and calls the thread to exit. The parameter is the return value of the thread function, or the parameter can be set to NULL;

There are three ways to exit a thread: 1 to return a thread function, 2 to call pthread_exit, and 3 to call pthread_cancel.

 

One thread can request to abort another thread. You only need to callPthread_cancel (PID)The cancel thread can be pthread_wait (PID). This wait function will release the resources occupied by the thread unless it is a detach thread;

Whether a thread can be canceled (cancel) is an attribute of a thread, similar to the "separation" attribute. The thread calls pthread_setcancelstatus () to realize whether it can be cancel. Note the difference between the pthread_attr_setxxx function group;

Pthread_setcancelstatus (pthread_calcel_disable, null );// The call thread cannot be canceled!

Pthread_setcancelstatus (pthread_calcel_enable, null );// If the second parameter is not null, the cancellation status of the previous state of the thread is stored;

In general applications, you can set a code range for pthread_setcancelstatus. in this range, threads cannot be canceled. For example, for bank transfers, two steps are required. Account A is deducted, and account B is added, in this process, you do not want the thread to be canceled;

 

7. mutex:

// Initialization

Int pthread_mutex_init (pthread_mutex_t *, pthread_mutexattr_t *); // The second parameter null is a structure pointing to the mutex lock type, representing the mutex lock of the default attribute;

The code for initializing the mutex lock attribute is as follows:

Pthread_mutex_t mutex;

Pthread_mutexattr_t ATTR;

Phtread_mutexattr_init (& ATTR );

Pthread_mutexattr_setkind_np (& ATTR, pthread_mutex_errorcheck_np );// Set the mutex type

Pthread_mutex_init (& mutex, & ATTR );// Initialize the mutex

Pthread_mutex_destory (& ATTR );// The variable pthread_mutexattr_t is destroyed after being used.

// Note: "non-portable" is ended with _ NP and cannot be transplanted.

 

Or initialize the mutex method in a simpler way:

Pthread_mutex_t mutex = pthread_mutex_initializer;// Fast Mutual Exclusion

Pthread_recursive_mutex_initializer_np: recursive mutex. When you lock a locked mutex, it does not block but records the number of times. The unlock must have the same number of times;

Pthread_checkerror_mutex_initializer_np: Error Correction mutex,

 

// Lock the mutex

Int pthread_mutex_lock (pthread_mutex_t * mutex );// Return 0 successfully

If mutex is locked by thread a and thread B tries to lock the mutex, thread B will be blocked until thread a removes the mutex lock, multiple Threads may be blocked on a mutex at the same time;

 

// Mutex deadlock

There are three types of mutex: Fast mutex (default type), recursive mutex (recursive mutex), error-checking mutex (error correction mutex ),

Possible deadlock: two threads and two mutex are locked at the same time, and mutual wait occurs, that is, deadlock. Example code:

 

// Thread a <br/> while (1) {<br/> mutex_lock (L1); <br/> mutex_lock (L2); <br/> do_joba (); <br/> mutex_unlock (L2); <br/> mutex_unlock (L1); <br/>}< br/> // thread B <br/> while (1) {<br/> mutex_lock (L2); <br/> mutex_lock (L1); <br/> do_jobb (); <br/> mutex_unlock (L1 ); <br/> mutex_unlock (L2); <br/>}< br/>/* <br/> process A: mutex_lock (L1); <br/> simultaneous process B: mutex_lock (L2); deadlock */ 

 

// Non-blocking lock mutex:

Int pthread_mutex_trylock (pthread_mutex_t * mutex );

/* If the mutex is successfully locked, 0 is returned. If the mutex is locked by another thread, ebusy is returned and no blocking is performed */

 

Sample Code:

Int ret = pthread_mutex_trylock (& mutex );

If (ret = ebusy ){

/* The mutex has been locked and is not blocked */

}

Else if (ret = einval ){

Assert (0 );/* Invalid attribute */

}

Else {

/* Unlock successfully and perform key code operations */

Ret = pthread_mutex_unlock (& mutex );

}

 

// Unlock the mutex

Int pthread_mutex_unlock (pthread_mutex_t * mutex );// Return 0 successfully

 

 

// Destroy the mutex

Int pthread_mutex_destory (pthread_mutex_t *);// Clear the mutex lock at the end of the program or other positions. The mutex cannot be in the locked state at this time;

 

8. Thread condition Variables

In the case of a, let the thread continue to execute, and block the thread in the case of B. When the blocking condition changes, all threads blocked by this condition variable can be activated;

This is applicable to the simplest scenario. For example, thread thread1 needs to cyclically extract the last node from the queue, thread thread2 needs to add nodes to the queue, or more read/write threads can operate on one queue together;

Generally, when all threads are in a while (1) loop, pthread_mutex_lock and _ unlock protect a code area. Check whether the queue is empty. Why is this efficiency not high?

 

(1)

Int pthread_cond_init (pthread_cond_t *, null );// If the second parameter is null, the default attribute is created.

 

(2) Conditional Variable waiting:

Int pthread_cond_wait (pthread_cond_t *, pthread_mutex_t *);

Before setting threada and executing the pthread_cond_wait function, you must lock the mutex. pthread_cond_wait takes an atomic operation to [unlock the mutex] and [start to wait for the signal]. Then the thread is equivalent to the wait or sleep state, the processor will process other threads at this time;

When a thread sends a signal to threada, threada returns and locks the mutex from the pthread_cond_wait function;

 

// Cond sample code ()

// Work_load indicates the current load. When max_work_load is exceeded, the consumer thread calls the process () function to reduce work_load; the producer thread sends a signal every time after work_load ++;

Pthread_mutex_lock (& mutex );

While (work_load <max_work_load)

Pthread_cond_wait (& cond, & mutex );

Process (); // partial protection Processing

Pthread_mutex_unlock (& mutex );

 

 

// Cond sample code (B)

// Queue indicates a linked list composed of task queues. The consumer thread extracts and processes nodes from the linked list, and the producer adds nodes to the linked list.

/* Thread consumer */

Void * Consumer (void *){

While (! Exit ){

Pthread_mutex_lock (& mutex );

Pthread_cond_wait (& Cond );// Mutually exclusive settings are not locked, waiting for conditional Signals

/* Receives the signal. When returned from the wait function, the mutex is set to lock. Queue -- operation */

Pthread_mutex_unlock ();

}

Printf ("Recv exit single/N ");

Return;

}

/* Thread producer */

Void * producer (void *){

Pthread_mutex_lock (& mutex );

/* Queue ++ */

Pthread_cond_signal (& Cond); // or broadcast

Pthread_mutex_unlock (& mutex );

Return;

}

// Note: For code robustness, the above wait function should check the returned value by assert.

 

(3) another type of Conditional Variable wait function, which specifies the maximum wait time. If no conditional signal arrives, etimeout is returned from function _ Wait:

Prototype: int pthread_cond_timewait (pthread_cond_t *, pthread_mutex_t *, const struct timespec *);

 

Pthread_mutex_lock (& mutex );

Int ret = pthread_cond_timewait (& cond, & mutex, & time );

If (ret = etimeout) {/* No signal received, time out */}

Else {/* receive conditional signal */}

 

(4) conditional signal sending Function

Int pthread_cond_signal (pthread_cond_t *);

Int pthread_cond_broadcast (pthread_cond_t *);

 

(5) destroy the condition variable. In gun/Linux, no resources are actually allocated to the condition variable. Destroy simply checks whether there are threads waiting for this condition variable;

Int pthread_cond_destory (pthread_cond_t *);

 

 

9. Thread semaphores

Involved type: sem_t

Involved functions: sem_init, sem_destory, sem_getvalue;

Semaphores are PV atomic operations applied by the operating system. They are widely used for synchronization and mutex between threads and processes. semaphores are essentially non-negative integer counters;

/* -- Principle of PV atomic operation: integer counter Sem. One P operation reduces SEM by 1, and one V Operation increases SEM by 1. When SEM is greater than or equal to 0, the thread has access to public resources. When SEM is less than 0, the thread will be blocked until SEM> = 0 */

PV atomic operations are used for "Mutual Exclusion" or "synchronization" operations;

 

 

(3) blocking and non-blocking functions. After a function is called, will the code be blocked here and wait for the function to return?

Single thread + blocking function, multi thread + blocking function?

Pthread_join/pthread_mutex_lock/pthread_mutex_trylock/pthread_cancel/pthread_wait

_ Mutex_trylock: If the mutex is locked, it will not be blocked;

_ Mutex_lock: If the mutex is not locked, it is not blocked. If the mutex is locked, it is blocked here;

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.