Problem Description: There are two threads, the main thread is responsible for receiving the data, and is temporarily stored in memory, when the amount of memory reaches a certain amount of data, batch submitted to Oracle, and another thread as the submission thread, periodically check, regardless of the amount of data in memory, the data submitted to Oracle on a regular basis. Two threads concurrent, the first write memory or database, the submission thread needs to hang, conversely, the main thread also need to be suspended. So, deliberately to understand the C + + multithreading in the concept of mutexes, a simple application.
--------------------------------------------------------------------------------------------------------------- -----------------
This article is written in simple and understandable, worthy of novice learning: http://blog.chinaunix.net/uid-21411227-id-1826888.html
In addition, there is an article that provides a packaged mutex program to learn: http://blog.csdn.net/chexlong/article/details/7058283
1. Introduction:
A mutex is a semaphore that is often used to prevent two of processes or threads from accessing the same shared resource at the same time . The following three points can be guaranteed:
Atomicity: Locking a mutex to an atomic operation means that the operating system (or Pthread function library) guarantees that if a thread locks a mutex, no other thread can successfully lock the mutex at the same time.
Uniqueness: If a thread locks a mutex, no other thread can lock the mutex until it unlocks.
Non-busy wait: If a thread has locked a mutex, the second thread attempts to lock the mutex, and the second thread is suspended (without any CPU resources) until the first thread unlocks the mutex, and the second thread wakes up and continues executing, locking the mutex.
From the above three points, we see that the mutex can be used to guarantee exclusive access to variables (critical code snippets).
2. Function Description:
Required header file: Pthread.h
1 ) Initialize the mutex
Function prototypes:int pthread_mutex_init (pthread_mutex_t *mp, const pthread_mutexattr_t *mattr)
Parameter description: MP Mutex address MattR property usually default null
Before you initialize a mutex, you must clear the memory in which it resides.
If the mutex is initialized, it is in an unlocked state. Mutexes can be in memory shared between processes or in the private memory of a process.
2 Lock Mutual-exclusion lock
Function Prototypes:
int Pthread_mutex_lock (pthread_mutex_t *mutex); #include <pthread.h> pthread_mutex_t mutex; int ret; ret = Pthr Ead_ Mutex_lock (&MP); /* Acquire the mutex * *
Function Description:
When Pthread_mutex_lock () is returned, the mutex is locked. The calling thread is the owner of the mutex. If the mutex is already locked and owned by another thread, the calling thread blocks until the mutex becomes available.
If the mutex type is pthread_mutex_normal, deadlock detection is not provided. Attempting to lock the mutex will result in a deadlock. If a thread attempts to unlock a mutex that is not locked or unlocked by that thread, an indeterminate behavior is generated.
If the mutex type is Pthread_mutex_errorcheck, error checking is provided. If a mutex that a thread attempts to unlock is already locked by that thread, an error is returned. If a thread attempts to unlock a mutex that is not locked or unlocked by that thread, an error is returned.
If the mutex type is pthread_mutex_recursive, the mutex retains the notion of a lock count. The lock count is set to 1 when the thread first succeeds in acquiring a mutex. The lock count increases by 1 each time the thread locks the mutex once. Each time the thread unlocks the mutex, the lock count is reduced by 1. When the lock count reaches 0, the mutex is available for other threads to acquire. If a thread attempts to unlock a mutex that is not locked or unlocked by that thread, an error is returned.
If the mutex type is Pthread_mutex_default, attempting to lock the mutex recursively will result in an indeterminate behavior. For a mutex that is not locked by the calling thread, an indeterminate behavior can occur if an attempt is made to unlock it. If you attempt to unlock a mutex that has not been locked, an indeterminate behavior occurs.
return value:
Pthread_mutex_lock () returns zero after successful completion. Any other return value indicates an error occurred. If any of the following conditions occur, the function will fail and return the corresponding value.
Eagain: The mutex cannot be acquired because the maximum number of mutex recursive locks has been exceeded.
EDEADLK: The current thread already has a mutex.
3 unlock Mutual exclusion lock
Function Prototypes:
int Pthread_mutex_unlock (pthread_mutex_t *mutex); #include <pthread.h> pthread_mutex_t Mutex; int ret; ret = Pthread_mutex_unlock (&mutex); /* Release the Mutex * *
Function Description: Pthread_mutex_unlock () frees the mutex object referenced by the mutex. How the mutex is disposed depends on the type attribute of the mutex. If multiple threads are blocked by a mutex object when a call to Pthread_mutex_unlock () is made, the mutex becomes available when the scheduling policy determines the thread that acquires the mutex. For pthread_mutex_recursive-type mutexes, the mutex becomes available when the count reaches 0 and the calling thread no longer locks the mutex.
return value: Pthread_mutex_unlock () returns zero after successful completion.
Any other return value indicates an error occurred. The function will fail and return the corresponding value if the following conditions occur.
Eperm: The current thread does not own a mutex.
4 Use non-blocking Mutex lock
Function Prototypes:
int Pthread_mutex_trylock (pthread_mutex_t *mutex); #include <pthread.h> pthread_mutex_t Mutex; int ret; ret = Pthread_mutex_trylock (&mutex); /* Try to lock the mutex */
Function Description: Pthread_mutex_trylock () is a non-blocking version of Pthread_mutex_lock (). If the mutex referenced by the mutex is currently locked by any thread (including the current thread), the call is returned immediately. Otherwise, the mutex is locked and the calling thread is its owner.
return value: Pthread_mutex_trylock () returns zero after successful completion. Any other return value indicates an error occurred. If any of the following conditions occur, the function will fail and return the corresponding value.
Ebusy:
The mutex cannot be acquired because it points to a mutex that is locked.
Eagain: Description:
The mutex cannot be acquired because it has exceeded the maximum number of recursive locks for the mutex.
5) Destroy the mutual-exclusion lock
Function Prototypes:
int Pthread_mutex_destroy (pthread_mutex_t *mp); #include <pthread.h> pthread_mutex_t MP; int ret; ret = Pthread_mutex_destroy (&MP); /* Mutex is destroyed */note that the space used to store the mutex is not released.
return value:
Pthread_mutex_destroy () returns zero after successful completion. Any other return value indicates an error occurred. If any of the following conditions occur, the function will fail and return the corresponding value.
EINVAL:MP The specified value does not reference an initialized mutex object.
3. Example:
Mutexes are used to ensure that only one thread executes a piece of code over a period of time. The need is obvious: assuming that each thread writes data to the same file order, the resulting result must be catastrophic.
Let's look at the following code first. This is a read/write program that has a common buffer, and we assume that a buffer can only hold one piece of information. That is, the buffer has only two states: there is information or no information.
void reader_function (void);
void writer_function (void);
char buffer;
int buffer_has_item=0;
pthread_mutex_t Mutex;
struct TIMESPEC delay;
void Main (void) {
pthread_t reader;
/* Define DELAY time * *
Delay.tv_sec = 2;
Delay.tv_nec = 0;
/* Initializes a mutex object with the default property * *
Pthread_mutex_init (&mutex,null);
Pthread_create (&reader, Pthread_attr_default, (void *) &reader_function), NULL);
Writer_function ();
}
void Writer_function (void) {
while (1) {
/* Lock Mutual-exclusion lock * *
Pthread_mutex_lock (&mutex);
if (buffer_has_item==0) {
Buffer=make_new_item ();
Buffer_has_item=1;
}
/* Open Mutual exclusion lock * *
Pthread_mutex_unlock (&mutex);
PTHREAD_DELAY_NP (&delay);
}
}
void Reader_function (void) {
while (1) {
Pthread_mutex_lock (&mutex);
if (buffer_has_item==1) {
Consume_item (buffer);
buffer_has_item=0;
}
Pthread_mutex_unlock (&mutex);
PTHREAD_DELAY_NP (&delay);
}
}
Program Description:
A mutex variable mutex is declared here, and the struct is pthread_mutex_t to a data type that is not exposed, and contains a system-assigned Property object. function pthread_mutex_init is used to generate a mutual exclusion lock. The null parameter indicates that the default property is used. If you need to declare a mutex for a particular attribute, you must call the function Pthread_mutexattr_init. function pthread_mutexattr_setpshared and function Pthread_mutexattr_settype are used to set mutex properties. The previous function sets the property pshared, which has two values, Pthread_process_private and pthread_process_shared. The former is used to synchronize threads in different processes, which are used to synchronize different threads of this process.
In the example above, we are using the default property Pthread_process_ PRIVATE. The latter is used to set the mutex type, and the optional types are pthread_mutex_normal, Pthread_mutex_errorcheck, pthread_mutex_recursive, and PTHREAD _mutex_default. They define different locking and unlocking mechanisms, and generally choose the last default attribute.
The Pthread_mutex_lock declaration begins with a mutex lock, and the following code is locked until the call to Pthread_mutex_unlock, which can only be executed by one thread at a time. When a thread executes to pthread_mutex_lock, if the lock is used by another thread at this time, the thread is blocked, which means that the program waits to another thread to release the mutex. In the example above, we used the PTHREAD_DELAY_NP function to allow a thread to sleep for a period of time in order to prevent a thread from always occupying this function.
4. The situation of starvation and deadlock
When a mutex is locked by another thread, and the other thread calls the Pthread_mutex_lock () function to lock it, it suspends its own thread and waits for the mutex to be unlocked. The following two scenarios may occur:
"Starvation": This mutex has not been unlocked, and the thread waiting to lock it will always be hung, that is, it requests a resource, but never gets it. The user must try to avoid this "starvation" state in the program. The Pthread function library does not automatically handle this situation.
Deadlock: All threads in a set of threads are waiting for resources to be occupied by other threads in the same group, at which point all threads are suspended because they wait for the mutex, and none of them will be able to resume operation and the program cannot continue. Then a deadlock is created. The Pthread function library can track this situation, when the last thread attempts to invoke Pthread_mutex_lock () fails and returns an error of type Edeadlk.