Pthread Programming Basics __ Programming

Source: Internet
Author: User
Tags mutex posix terminates
1. Pthread Thread Concept

The multithreading under Linux system follows the POSIX thread interface, called Pthread. Write a multithreaded program under Linux, you need to use the header file Pthread.h, the connection needs to use the library LIBPTHREAD.A. Similar to the concept of task on VxWorks, it is the smallest unit of dispatch, which has shared heap, stack, code area, global variable and so on. 2. Creating Threads

int pthread_create (pthread_t * thread,

pthread_attr_t * attr,

void * (*start_routine) (void *),

void * arg)

Thread: Returns the ID of the threads created

attr: Thread attributes, scheduling policy, priority, etc. are set here, and if NULL, the default attribute is used

Start_routine: A thread-entry function that returns a void* type return value that can be captured by Pthread_join ()

ARG: argument passed to Start_routine, can be null

Return value: Successfully returned 0

3. Set thread Properties

Thread properties are set through attr.

Set and query attr structure for pthread_attr_get*** () and pthread_attr_set*** () two function series.

Set the pthread_get*** () and pthread_set*** () two function series for the query thread parameters. You can also pass pthrea_create to parameters at creation time.

Note: Some must be set when the thread is created, such as a scheduling policy.

3.1. Scheduling Strategy

There are three types of scheduling strategies:

Sched_other: Not real time, normal

SCHED_RR: Real time, polling method

Sched_fifo: Real time, first-in-first out, consistent with VxWorks scheduling mechanism

Routines:

pthread_attr_t attr;

Pthread_attr_init (&ATTR);

Pthread_attr_setschedpolicy (&attr, Sched_fifo);//sched_policy

3.2. Priority level

The thread priority supports two sets of settings, one is the creation time setting, the other is the dynamic setting after the creation

Routines:

Pthread_attr_setschedparam (&attr, new_priority);

If this is a static setting, then the task is created with this property and, if it is dynamic, the following function settings are used:

Pthread_attr_setschedparam (&attr, &task->prv_priority);

Pthread_attr_getschedparam (&attr, &schedparam);

schedparam.sched_priority = new_priority;

Pthread_attr_setschedparam (&attr, &schedparam);

Pthread_setschedparam (Pthrid, Sched_policy, &schedparam);

3.3. Out of sync

The Pthread_join () function keeps the main thread synchronized with child threads. If the Detachstate state is set, the Pthread_join () is invalidated and the thread automatically releases the resources it occupies. The default state of the thread is the phread_create_joinable state, and once the thread is run, it cannot be restored to the joinable state once it is set to the Pthread_create_detach state.

Routines:

Pthread_attr_setinheritsched (&attr,pthread_explicit_sched);

3.4. Dispatch inheritance

Thread A creates thread B, then thread B's scheduling policy is related to thread A's scheduling policy and thread B's inheritance policy. If the thread B inheritance policy is pthread_inherit_sched, thread B's scheduling policy is the same as thread A; if the thread B inheritance policy is pthread_explicit_sche, then the scheduling policy for thread B is determined by attr.

Pthread_attr_setdetachstate (&attr,pthread_create_detached);

4. Thread Cancellation

4.1. Thread Cancellation definition

A pthread thread can terminate the operation of a thread by sending a cancellation request.

The process of canceling a thread is primarily used in the following scenarios: A thread is using the Select Monitor network port, the master thread receives the user's notification at this point, and the host thread sends a cancellation request to the listener thread.

When a Linux pthread thread receives a cancellation request, it does not terminate the thread immediately, but rather waits until the cancellation point to complete the task. This allows us to establish some special processing for the cancellation point. Select is a cancellation point, so you can exit.

4.2. Cancellation Point

VxWorks can kill a task in any location, which causes the task to be killed after the position is not controllable, so vxworks will not rarely use Taskdeletehook.

Pthread the concept of a cancellation point. The thread can only be canceled at the point of cancellation, regardless of when the thread receives the cancellation request. This ensures that the risk is controllable.

The Pthread standard specifies the following cancellation points:

Øpthread_testcancel

Ø all dispatch points, such as pthread_cond_wait, sigwait, select, sleep, etc.

According to the POSIX standard, read (), write () and so on can cause blocking system calls are Cancelation-point, while other pthread functions do not cause cancelation action. But Pthread_cancel's hand album claimed that because the Linuxthread library and C library are not well combined, the C library function is not cancelation-point, You can therefore call Pthread_testcancel () before and after a system call that needs to be a cancelation-point to achieve the desired goal of the POSIX standard, which is the following code snippet:

Pthread_testcancel ();

Retcode = Read (fd, buffer, length);

Pthread_testcancel ();

This code guarantees that there is a cancellation point near the read, but it is possible that the card will not return in read.

If the thread is in an infinite loop and the loop body does not have the necessary path to the cancellation point, the thread cannot be terminated by the cancellation request of an external thread. Therefore, the Pthread_testcancel () call should be added to the necessary path of such a loop body.

4.3. Thread cancellation function

int Pthread_cancel (pthread_t thread)

Sends an abort signal to the thread thread and returns 0 if successful, otherwise it is not a 0 value. Sending success does not mean that thread will terminate.

int pthread_setcancelstate (int state, int *oldstate)

Set the response of this thread to the CANCEL signal, state has two values: pthread_cancel_enable (default) and Pthread_cancel_disable, respectively, the signal is set to cancled state and the cancel signal is ignored, and the old_state is deposited in the original cancel state if it is not null for recovery.

int pthread_setcanceltype (int type, int *oldtype)

Sets the timing for this thread to cancel the action, with type two values: Pthread_cancel_deffered and pthread_cancel_asychronous, only if the cancel state is enabled. respectively, after receiving the signal to continue to run to the next cancellation point and then exit and immediately perform the Cancel action (exit); Oldtype if not null, the original cancel action type value is saved.

void Pthread_testcancel (void)

Check whether this thread is in the Canceld state, if it is, cancel the action, or return directly.

4.4. Routine

#include <stdio.h>

#include <pthread.h>

#include <unistd.h>

pthread_key_t key;

pthread_mutex_t mutex = Pthread_mutex_initializer;

pthread_cond_t cond = Pthread_cond_initializer;

unsigned long abc=0;

void* Test03 (void *p)

{

printf ("Cancel Point");

return NULL;

}

void* Test01 (void* ptr)

{

Pthread_cleanup_push (Test03, NULL); /* Push * *

while (1)

{

abc++;

Pthread_testcancel ();

}

Pthread_cleanup_pop (0); /* Pop *

return NULL;

}

void* Test02 (void* ptr)

{

while (1)

{

Sleep (2);

printf ("2222cond_wait:abc=0x%08x\n", ABC);

}

return NULL;

}

int main (void)

{

int TID1, TID2;

int ret;

printf ("start:\n");

ret = pthread_create (&TID1, NULL, Test01, NULL);

ret = pthread_create (&TID2, NULL, Test02, NULL);

Sleep (6);

Pthread_cancel (TID1);

Pthread_join (TID1, NULL);

Pthread_join (Tid2, NULL);

return 0;

}

Results:

Start:

2222cond_wait:abc=0x22c29a05

2222cond_wait:abc=0x47b49007

Cancel POINT2222COND_WAIT:ABC=0X6C9DE3AD

2222cond_wait:abc=0x6c9de3ad

2222cond_wait:abc=0x6c9de3ad

Thread 1 cannot exit if Pthread_testcancel () is not added to the cancellation point.

5. Thread Termination Method

There are two cases of thread termination (regardless of process). One is when the thread body function return, the thread terminates automatically, the exit is predictable, and the other line Cheng the thread to send the cancellation request, and the thread will judge whether or not to terminate according to the situation, at which point the termination is unpredictable.

The tasks in VxWorks are similar to this. The task terminates automatically when the principal function of the task is return, and other tasks call Taskdelete () to kill any one task. Taskdelete () is not safe because the task may be killed at any one time.

5.1. Cleanup at end of thread

Whether it is a predictable thread termination or abnormal termination, there will be the issue of resource release, without considering the failure to exit due to the operation of the premise, how to ensure that the thread termination can smoothly release the resources occupied by their own, especially lock resources, is a must be considered to solve the problem.

The most common scenario is the use of resource exclusive locks: Threads are locked for access to critical resources, but are canceled during the access process, if the thread is in a response-cancellation state, respond asynchronously, or have a cancellation point on the run path prior to opening the exclusive lock. The critical resource is permanently locked out of the lock state. Outside cancellation is unpredictable, so it does require a mechanism to simplify programming for resource release.

A Pthread_cleanup_push ()/pthread_cleanup_pop () function pair is provided in the POSIX thread API to automatically release resources, which is equivalent to adding a destructor. The terminating action in the program segment from the call point of Pthread_cleanup_push () to the Pthread_cleanup_pop (), including the call to Pthread_exit () and the cancellation point termination), is performed pthread_cleanup_ The cleanup function specified by the push ().

The API is defined as follows:

void Pthread_cleanup_push (void (*routine) (void *), void *arg)

void Pthread_cleanup_pop (int execute)

Pthread_cleanup_push ()/pthread_cleanup_pop ()

Using the first-in-out stack structure management, the void routine (void *arg) function is pressed into the cleanup function stack when the Pthread_cleanup_push () is invoked, and multiple pairs of pthread_cleanup_push () Call will form a function chain in the cleanup function stack, which pops up in the reverse order of the stack when the function chain is executed.

The Execute parameter indicates whether execution to Pthread_cleanup_pop () executes the function while the cleanup function is ejected, 0 for not executing, not 0 for execution, and this parameter does not affect execution of the cleanup function when the exception terminates.

These two are actually macros that must appear in pairs, or they will compile.

Compile. In the following example, when the thread terminates in "Do some work", the Pthread_mutex_unlock (Mut) is invoked actively to complete the unlock action.

Pthread_cleanup_push (Pthread_mutex_unlock, (void *) &mut);

Pthread_mutex_lock (&mut);

/* Do some work * *

Pthread_mutex_unlock (&mut);

Pthread_cleanup_pop (0);

It is important to note that if the thread is in a pthread_cancel_asynchronous state, the code snippet above can be faulted because the CANCEL event may be in Pthread_cleanup_push () and Pthread_mutex_ Occurs between lock (), or between Pthread_mutex_unlock () and Pthread_cleanup_pop (), causing the cleanup function to unlock a mutex variable that is not locked, resulting in an error. Therefore, when using the cleanup function, it should be temporarily set to pthread_cancel_deferred mode. To do this, Pthread also provides a pair of pthread_cleanup_push_defer_np ()/pthread_cleanup_pop_defer_np () extension functions that do not guarantee portability, which is equivalent to the following code snippet:

{

int oldtype;

Pthread_setcanceltype (pthread_cancel_deferred, &oldtype);

Pthread_cleanup_push (routine, ARG);

...

Pthread_cleanup_pop (execute);

Pthread_setcanceltype (Oldtype, NULL);

}

5.2. Thread-terminated synchronization and its return value

In general, each thread in a process is running independently of each other, and the thread's termination does not notify or affect other threads, and the resources that are consumed by the terminated thread are not released as the thread terminates. Just as a wait () system can be used to synchronize the termination and release of resources between processes, there is a similar mechanism between threads, and that is the Pthread_join () function.

void Pthread_exit (void *retval)

int Pthread_join (pthread_t th, void **thread_return)

int Pthread_detach (pthread_t th)

The caller of Pthread_join () hangs and waits for the th thread to terminate, retval is the return value of the pthread_exit () caller thread (thread ID th), and if Thread_return is not NULL, *thread_return= retval Note that a thread allows only one thread to use Pthread_join () to wait for its termination, and that the waiting thread should be in a join state, i.e. a detached state.

If a thread in the process executes the pthread_detach (th), the th thread will be in the detached state, allowing the th thread to free itself from the memory resources it occupies while at the end of the run, and not to be synchronized by Pthread_join () Pthread_ After the detach () is executed, the pthread_join () for th request will return an error.

The memory occupied by a Pthread_join thread is released only when it has been executed by a wire thread (), so in order to avoid a memory leak, the termination of all threads is either set to detached or required to be reclaimed using pthread_join ().

5.3. About Ptread_exite () and return

Theoretically, the function of Pthread_exit () and the thread host function exits is the same, and when the function ends, the pthread_exit () is automatically invoked internally to clean up the thread-related resources. But in fact the two are very different because of compiler processing.

Calling Pthread_exit () in the process main function (main ()) only causes the thread of the main function to exit (which can be said to be the primary thread of the process), and if it is return, the compiler will make it call the process exit code (such as _exit ()), Which causes the process and all its threads to end running.

Second, the active invocation of return in the thread host function, if the return statement is contained in the Pthread_cleanup_push ()/pthread_cleanup_pop () pair, does not cause the cleanup function to execute, but instead causes the segment Fault

5.4. Judge whether the same thread

int pthread_equal (pthread_t thread1, pthread_t thread2)

Determines whether two thread descriptors point to the same line. In Linuxthreads, threads with the same thread ID are necessarily the same thread, so the implementation of this function simply determines whether thread1 and thread2 are equal.

5.5. Perform only one operation

int pthread_once (pthread_once_t *once_control, Void (*init_routine) (void))

This function uses the Once_control variable with the initial value of Pthread_once_init to guarantee that the Init_routine () function is executed only once in this process execution sequence. This is similar to the thread constructor.

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.