Why are you so afraid of multithreaded programming? Pthread,sem,mutex,process

Source: Internet
Author: User
Tags exit in function prototype mutex semaphore signal handler terminates

Transfer from http://blog.chinaunix.net/uid-20788636-id-1841334.html

1. Thread creation and exit
Creating a thread is essentially determining the entry point to invoke the thread function, which is typically used in pthread_create. After the thread has been created, it starts to run the related threading function, and after the function has finished running, the thread exits, which is also a way for the thread to exit. Another way to exit the thread is to use the function Pthread_exit, which is the active behavior of the threads. Use Pthread_exit in the thread instead of exit in the process.
Because more than one thread in a process is a shared data segment, the resources that are consumed by the exit thread will not be freed as the thread terminates after threads are usually exited. Just as there is a wait () system transfer between processes to terminate and release resources synchronously, there is a similar mechanism between threads, which is the Pthread_join () function. Pthread_join can be used to suspend the current thread, waiting for the end of the thread. This function is a thread-blocking function, and the function that invokes it waits until the waiting thread ends, and when the function returns, the resource that is waiting for the thread is retracted.

function format
Pthread_create
Required header File #include
function prototype int pthread_create ((pthread_t *thread, pthread_attr_t *attr, void * (*start_routine) (void *), void *arg))
function passed in value thread: thread identifier
attr: Thread property setting
Start_routine: Start address of the thread function
ARG: Arguments passed to the Start_routine
function return value succeeded: 0
Error:-1

Pthread_exit

Required header File #include
function prototype void pthread_exit (void *retval)
The function passes in the value retval:pthread_exit () The return value of the caller thread, which can be retrieved by other functions such as Pthread_join

Pthread_join

Required header File #include
function prototype int pthread_join ((pthread_t th, void **thread_return))
function passed in value th: The identifier of the waiting thread
Thread_return: User-defined pointer to store the return value of the waiting thread (when not NULL)
function return value succeeded: 0
Error:-1
2. Modify Thread Properties

The second parameter of the Pthread_create function, the thread's property, sets the value to null, that is, with the default property, the multiple properties of the thread can be changed. These properties mainly include binding properties, detached properties, stack addresses, stack sizes, and precedence. The default properties of the system are unbound, non-detached, default 1M stacks, and the same level of precedence as the parent process.
A. Binding Properties
Linux uses a "one-on-one" threading mechanism, which is a user thread that corresponds to a kernel thread. A binding attribute means that a user thread is pinned to a kernel thread, because the CPU time slice is scheduled to target a kernel thread (that is, a lightweight process), so a thread with a bound attribute can guarantee that there will always be a kernel thread corresponding to it when needed. The relative non-binding attribute means that the relationship between the user thread and the kernel thread is not always fixed, but is controlled by the system.
B. Separating properties
The detach attribute is used to determine how a thread terminates itself. In a non-detached situation, when a thread ends, the system resources it consumes are not released, that is, there is no real termination. Only when the Pthread_join () function returns does the created thread release the system resources that it occupies. In the case of detached attributes, the system resources that it occupies are released immediately at the end of a thread. One thing to note here is that if you set the Detach property of a thread and the thread is running very fast, it is likely to terminate before the Pthread_create function returns, and it will probably pass the thread number and system resources to other threads for use when it terminates, calling Pthread_ The thread of create gets the wrong thread number.
The settings for these properties are done by a certain function, usually first calling the Pthread_attr_init function to initialize, before invoking the corresponding property-setting function. The function that sets the binding property is Pthread_attr_setscope, the function that sets the thread detach property is Pthread_attr_setdetachstate, and the correlation function that sets the thread priority is PTHREAD_ATTR_ Getschedparam (get thread priority) and Pthread_attr_setschedparam (set thread priority). After you have set these properties, you can call the Pthread_create function to create the thread.

Pthread_attr_init
function prototype int pthread_attr_init (pthread_attr_t *attr)
function passed in value attr: Thread Properties
function return value succeeded: 0
Error:-1

Pthread_attr_setscope
function prototype int pthread_attr_setscope (pthread_attr_t *attr, int scope)
function passed in value attr: Thread Properties
Scope:pthread_scope_system: Binding
Pthread_scope_process: Non-binding
function return value succeeded: 0
Error:-1

Pthread_attr_setdetachstate
function prototype int pthread_attr_setscope (pthread_attr_t *attr, int detachstate)
function passed in value attr: Thread Properties
Detachstate pthread_create_detached: Separation
PTHREAD _create_joinable: Non-separable
function return value succeeded: 0
Error:-1

Pthread_attr_getschedparam
function prototype int Pthread_attr_getschedparam (pthread_attr_t *attr, struct Sched_param *param)
function passed in value attr: Thread Properties
PARAM: Thread Priority
function return value succeeded: 0
Error:-1

Pthread_attr_setschedparam
function prototype int Pthread_attr_setschedparam (pthread_attr_t *attr, struct Sched_param *param)
function passed in value attr: Thread Properties
PARAM: Thread Priority
function return value succeeded: 0
Error:-1
3. Thread Access Control

there are mainly mutexes and semaphores.

A.mutex Mutex Thread control

A mutex is a simple lock-in method to control access to shared resources. There are only two states of this mutex, that is, lock and unlock, and you can think of the mutex as a global variable in a sense. Only one thread can hold a lock on a mutex at the same time, and a locked thread can manipulate the shared resource. If another thread wants to lock a locked mutex, the thread hangs until the locked thread releases the mutex. It can be said that this mutex allows shared resources to be manipulated sequentially in each thread.
The operation of the mutex mainly consists of the following steps.
Mutex initialization: Pthread_mutex_init
Mutex Lock: Pthread_mutex_lock
Lock Mutex: Pthread_mutex_trylock
Mutex unlock: Pthread_mutex_unlock
Eliminate mutex: Pthread_mutex_destroy
Among them, the mutex can be divided into fast mutex, recursive mutex and error-checking mutex. The difference between the three types of locks is primarily the need for blocking waits for other threads that do not occupy the mutex when they want the mutex to be locked.
A quick lock is a call thread that blocks until the line threads unlocked that owns the mutex.
Recursive mutexes can successfully return and increase the number of times the calling thread locks on the mutex.
A fault-checking mutex is a non-blocking version of a fast mutex that returns immediately and returns an error message.

Pthread_mutex_init
function prototype int pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
function passed in value mutex: Mutex
Pthread_mutex_initializer: Creating a quick Mutex
Mutexattr pthread_recursive_mutex_initializer_np: Creating a recursive mutex
PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: Creating a fault-checking mutex
function return value succeeded: 0
Error:-1

Pthread_mutex_lock
function prototype int Pthread_mutex_lock (pthread_mutex_t *mutex,)
int Pthread_mutex_trylock (pthread_mutex_t *mutex,)
int Pthread_mutex_unlock (pthread_mutex_t *mutex,)
int Pthread_mutex_destroy (pthread_mutex_t *mutex,)
function passed in value mutex: Mutex
function return value succeeded: 0
Error:-1
B. Semaphore Threading Control

The semaphore is the PV primitive used in the operating system, which is widely used for synchronization and mutual exclusion between processes or threads. The semaphore is essentially a nonnegative integer counter that is used to control access to public resources.
The PV primitive is the operation of the integer counter semaphore sem. One P operation causes the SEM to subtract one, and one v operation causes the SEM to add one. The process (or thread) determines whether access to a public resource is available based on the value of the semaphore. When the value of the semaphore SEM is greater than or equal to zero, the process (or thread) has access to the public resource; Conversely, when the value of the semaphore SEM is less than zero, the process (or thread) will block until the value of the SEM of the semaphore is greater than or equal to 0.
The PV primitive is primarily used for both synchronization and mutex between processes or threads. If used for mutual exclusion, several processes (or threads) tend to only set a semaphore SEM, as shown in operation Flow 9.2.
When semaphores are used for synchronous operations, multiple semaphores are often set and different initial values are arranged to implement the order between them.

Sem_init is used to create a semaphore and to initialize its value.
Sem_wait and sem_trywait are equivalent to P operations, they all can reduce the value of the semaphore by one, the difference is that if the signal volume is less than zero, SEM_WAIT will block the process, and Sem_trywait will return immediately.
The sem_post is equivalent to a V operation, which adds the value of the semaphore to a process that signals a wake-up wait at the same time.
The sem_getvalue is used to get the value of the semaphore.
Sem_destroy is used to remove semaphores.

Sem_init
Required header File #include
function prototype int sem_init (sem_t *sem,int pshared,unsigned int value)
Function incoming value SEM: semaphore
Pshared: Determines whether the semaphore can be shared between several processes. Since Linux has not yet implemented shared semaphores between processes, this value can only take 0
Value: Semaphore initialization value
function return value succeeded: 0
Error:-1

Sem_wait
function prototype int sem_wait (sem_t *sem)
int sem_trywait (sem_t *sem)
int Sem_post (sem_t *sem)
int Sem_getvalue (sem_t *sem)
int Sem_destroy (sem_t *sem)
Function incoming value SEM: semaphore
function return value succeeded: 0
Error:-1

================================

Transferred from: http://blog.csdn.net/sharelearner/article/details/9750273

What does Pthread_join do?

This function is mainly to solve the problem of resource recycling!

What is the problem?

In Linux, by default, after a thread is created, you must use this function to recycle the created thread, but you can also

Set the threads attributes (binding property, detach attribute, stack address, stack size, priority) to set the resource that is consumed by this thread when a thread ends.

In fact, in Linux, the new thread is not in the original process, but the system through a call to Clone (), the system copy a process identical to the original processes, and in this process to execute the thread function.

However, the copy process is not the same as the fork, and the copied process and the original process share all the variables and the operating environment. The variable changes in this process are reflected in the copy-after process.

---!!! So what does the Pthread_join function do?

If there is no pthread_join in the code, the main thread can end up so that the entire process ends, so that the created threads end up without a chance to start executing. Without setting the Detach property of the new thread, after joining Pthread_join, the main thread waits until the thread that until waits for ends----> then the main thread itself ends, allowing the created threads to have the opportunity to execute.

All threads have a thread number, which is ThreadID, type pthread_t, which can be obtained by calling the Pthread_self () function.

In multithreaded programming, we often call the Pthread_join function in the form of a for loop, since running Pthread_join, the main thread is blocked, there is no way to call the back of the Pthread_join, why also use for loop?

But this is the process:

Pthread_join (1,null)

Pthread_join (2,null)

Pthread_join (3,null)

Pthread_join (4,null)

Pthread_join (5,null)

The main thread hangs at the first pthread_join (1,null) thread, then at the end of line Line 1, wait for line Line 2, line Line 3.

Of course, there will be 3, 4, Line 5 line than the first case of the end; Then the 3,4,5 thread ends, and the 3,4,5 resource is not released. Because the main thread or block waiting to reclaim 1, Line 2 line of resources, wait until 1, Line 2 line end, then 3,4,5 resources, then the main thread and then exit.

========================================

Transferred from: http://blog.csdn.net/sharelearner/article/details/11533367

Pthread_kill:

Don't be frightened by the name,Pthread_kill is not kill, but sends signal to the thread. Remember signal, the default action for most signal is to terminate the process, so we need to use signal () to catch the signal and add the processing function.

int Pthread_kill (pthread_t thread, int sig);

The sig signal is sent to the thread that specifies the ID, and if the thread code does not handle it, the entire process is affected by the default behavior of the signal, that is, if you send a sigquit to a thread, but the thread does not implement the signal handler, the entire process exits.

Pthread_kill (ThreadID, SIGKILL), too, kills the whole process.
If you want to get the right behavior, you need to implement signal (Sigkill,sig_handler) within the thread.

So, if the int sig parameter is not 0, it must be clear exactly what to do, and must implement the signal processing function of the thread, otherwise, it will affect the entire process.


OK, if the int sig is 0, this is a reserved signal and a function is used to determine if the thread is still alive.

Let's take a look at the return value of Pthread_kill:
Success: 0
Thread does not exist: Esrch
Signal not valid: EINVAL

So, Pthread_kill (threadid,0) is very useful.

int KILL_RC = Pthread_kill (thread_id,0);

if (KILL_RC = = Esrch)
printf ("The specified thread did not exists or already quit/n");
else if (KILL_RC = = EINVAL)
printf ("Signal is invalid/n");
Else
printf ("The specified thread is alive/n");

The code above can tell if the thread is still alive.

Copyright notice: When reproduced, please indicate the original source and author information and this statement in the form of hyperlinks.
Http://xufish.blogbus.com/logs/40545082.html

Use the Pthread_kill function to detect if a thread is still alive, and in the Linux environment, GCC compiles, and now the code is posted below:

/*******************************pthread_kill.c*******************************/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>

void *func1 ()/* 1 seconds after exit */
{
Sleep (1);
printf ("Thread 1 (id:0x%x) exited. /n ", (unsigned int) pthread_self ());
Pthread_exit ((void *) 0);
}

void *func2 ()/* 5 seconds after exit */
{
Sleep (5);
printf ("Thread 2 (id:0x%x) exited. /n ", (unsigned int) pthread_self ());
Pthread_exit ((void *) 0);
}

return value of void Test_pthread (pthread_t tid)/*pthread_kill: Success (0) thread does not exist (Esrch) signal not in law (EINVAL) */
{
int pthread_kill_err;
Pthread_kill_err = Pthread_kill (tid,0);

if (Pthread_kill_err = = Esrch)
printf ("The thread with ID 0x%x does not exist or has exited.") /n ", (unsigned int) tid);
else if (Pthread_kill_err = = EINVAL)
printf ("Send the signal illegally.") /n ");
Else
printf ("The thread with ID 0x%x is still alive.") /n ", (unsigned int) tid);
}

int main ()
{
int ret;
pthread_t Tid1,tid2;

Pthread_create (&tid1,null,func1,null);
Pthread_create (&tid2,null,func2,null);

Sleep (3);/* After creating two processes for 3 seconds, test if they are still alive */

Test_pthread (TID1);/* Test if a thread with ID TID1 exists */
Test_pthread (TID2);/* Test if a thread with ID TID2 exists */

Exit (0);
}


Compilation: Gcc-o Pthread_kill-lpthread pthread_kill.c
Run:./pthread_kill

Run result/////////////////////////////
Thread 1 (id:0xb7e95B90) exit.
ID is 0xb7e95The B90 thread does not exist or has exited.
ID is 0xb7694The B90 thread is still alive.

Why are you so afraid of multithreaded programming? Pthread,sem,mutex,process

Related Article

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.