Mutual exclusion of multithreaded programming

Source: Internet
Author: User
Tags mutex usleep

Recently looking at the POSIX multithreaded programming, want to read the words I remember after reading a record, deepen memory.

If multiple threads read and write to the same memory region, a mutex can be used to ensure that a thread is atomic to the operation of that memory.

The use of multithreading is to make the program run to achieve concurrency or even parallel purposes, the use of mutexes so that multiple threads in the critical section can only one run.

The critical section refers to the piece of code that operates the global memory area.

The initialization of the mutex:

  pthread_t mutex = Pthread_mutex_initializer; Static Initialization

  pthread_mutex_init (); dynamic initialization, using dynamic initialization requires a combination of Pthread_mutex_destroy () Release Mutex amount

Three functions of the mutex amount:

  Pthread_mutex_lock (pthread_t *mutex);

  Pthread_mutex_trylock (pthread_t *mutex);

  Pthread_mutex_unlock (pthread_t *mutex);

Some of the above functions are written by impressions, and you need to check them out when you use them.

When it comes to mutual exclusion, it is inevitable to mention the deadlock, there are many reasons for the deadlock, the following situation is more typical,a process to 1 number of resources lock, at this time need

Resource Number 2 , while the B process adds a lock to the 2 Resource, it requires 1 resources at this time . In this case A waits for b to unlock resource 2 ,b waits A unlock a resource, A and the B have happened

Deadlock.

To produce the above situation, you need multiple shared resources first, and the second process is mutually exclusive to the use of shared resources, that is, only one process can occupy the resource at a time (

mutually exclusive condition), a process already occupies a resource, maintains the situation that the process occupies, and goes to get other resources (request and hold condition), the resources that the process has obtained,

You must not be deprived of your use until you have finished using it, and you can only use your own release (inalienable condition).

To avoid the deadlock method, the sequential locking method and the fallback algorithm can be used to avoid the deadlock of the above situation.

sequential lock method, such as its name, for shared resources 1 2 3 a b lock them in a uniform order, i.e. a 1 3 Lock, b also from 1

Avoid loop waits between a and B to form resources.

Fallback algorithm:a and B Each choose a direction to lock the shared resource group (the direction does not have to be the same),a first to lock the first resource ( Pthread_mutex_lock ()), plus lock

After the success of the other resources to perform a test lock (Pthread_mutex_trylock ()), if the attempt to lock the resource has been locked by other processes,A The process takes the resources it already occupies

The part is unlocked. In this way , other processes that require a resource of a can be chained successfully, avoiding deadlocks.

In the fallback algorithm, the first resource is directly locked instead of a test lock, I think because each process is in order to lock (regardless of the order is unified), if the first

Lock is not successful, it is basically not a deadlock. There's no need to unlock it once. The resource that the lock occupies (after all, the thread does not have a resource before locking the first resource).

The following program can be used to verify the fallback algorithm,backoff=0, two threads in reverse direction lock, generate deadlock,backoff=1, two threads in reverse direction lock, using the fallback algorithm, will not occur dead

Lock.

#include <stdio.h>
#include <pthread.h>
#include <errno.h>

pthread_mutex_t Mutex[3] = {
Pthread_mutex_initializer,
Pthread_mutex_initializer,
Pthread_mutex_initializer
};
void *thread_forward (void *);
void *thread_backward (void *arg);

int backoff = 1;
int main (int argc,char *argv[])
{
pthread_t Forward,backward;

if (ARGC < 2)
{
printf ("Need-prm\n");
return 0;
}

Backoff = Atoi (argv[1]);
Pthread_create (&forward,null,thread_forward,null);
Pthread_create (&backward,null,thread_backward,null);

Pthread_join (Forward,null);
Pthread_join (Backward,null);
return 0;
}

void *thread_forward (void *arg)
{
int i = 0;
int status = 0;

for  (;  i < 3; i++)
{
if  (0 == i)
{
Status  = pthread_mutex_lock (&mutex[i]);  
if  (status != 0)
{
printf ("Mutex _lock:%s ", strerror (status));
return null;
}
continue;
}
if  (!backoff)
{
Status = pthread_mutex_lock (&mutex[i]);  
if  (status  != 0)
{
printf ("mutex_lock:%s", strerror (status));
return null;
}
}
Else
{
Status = pthread_mutex_trylock (&mutex[i]);
if  (status == ebusy)
{
printf ("locked at:%d\n", I);
for  (;  i >= 0; i--)
{
Status = pthread_mutex_unlock (&mutex[i]) ;  
if  (status != 0)
{
printf ("mutex_unlock:%s", strerror (status));
return null;
}
}
}
}

Usleep (1); The no sleep () function may not see the effect of a deadlock, because one thread may have completed all mutex locking work before another thread executes
}
for (i = 2; I >= 0; i--)
{
Status = Pthread_mutex_unlock (&mutex[i]);
if (Status! = 0)
{
printf ("mutex_unlock:%s", strerror (status));
return NULL;
}
}
}

void *thread_backward (void *arg)
{
int i = 2;
int status = 0;

for  (;  i >= 0; i--)
{
if  (2 == i)
{
Status  = pthread_mutex_lock (&mutex[i]);  
if  (status != 0)
{
printf ("Mutex _lock,backward:%s ", strerror (status));
return null;
}
continue;
}
if  (!backoff)
{
Status = pthread_mutex_lock (&mutex[i]);  
if  (status  != 0)
{
printf ("mutex_lock:%s", strerror (status));
return null;
}
}
Else
{
Status = pthread_mutex_trylock (&mutex[i]);
if  (status == ebusy)
{
printf ("[bakckward],locked at:%d\n", i);
for  (;  i < 3; i++)
{
Status = pthread_mutex_unlock (&mutex[i]); &NBSP
if  (status != 0)
{
printf ("mutex_unlock:%s", strerror (status));
return null;
}
}
}
}

Usleep (1);
}
for (; i < 3; i++)
{
Status = Pthread_mutex_unlock (&mutex[i]);
if (Status! = 0)
{
printf ("mutex_unlock:%s", strerror (status));
return NULL;
}
}
}

Mutual exclusion of multithreaded programming

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.