Programming with threads requires skill, and bugs in multi-threaded programs are very difficult to track and debug, because these bugs are often hard to reproduce.
Competitive conditions:
When one thread accesses a data structure, the other thread also accesses the same data structure, and then there is a race condition-two threads (or multiple threads) competing for access to the same resource.
When one thread processes a part of the data, the other thread may process the same data, and for scheduling reasons, it runs faster than the previous one, the same processing may occur multiple times.
For example, a one-way linked list (Queue) that represents the task list, a thread reads the next task from the current element, and finds that the next task is not empty, prepare to set this task to null and execute the task;
At this time, the scheduling stops this thread, and the other thread also reads the next task from the current element. Of course, the next task is still not null, and this thread will also execute the next task. In this way, in some misfortune
The task is executed twice.
Even more unfortunate, the thread is interrupted during task execution. At this time, the other thread releases the memory of the task, and the thread in execution will cause a segment error.
If you are lucky, these things may never happen. But when the program runs in a system with a high load, this bug will be highlighted.
Mutex lock:
To eliminate the impact of competition conditions, some operations should be made "Atomic"-these operations can neither be separated nor interrupted.
When a thread locks the mutex lock and other threads require it to be locked, it will be blocked until the previous thread is unlocked, other threads can cancel blocking and resume running.
GNU/Linux ensures that the thread does not compete in the Process of locking the mutex lock. Only one thread can lock the mutex lock, and the lock requests of other threads will be blocked.
To create a mutex lock, you must:
Create a variable of the pthread_mutex_t type and pass its pointer to the pthread_mutex_init function. The second parameter of this function is a pointer to a mutex property object (this object is used to specify the mutex property. The mutex object can only be initialized once.
The simpler method of aggregate is to use pthread_mutex_initializer to obtain the default mutex object:
Pthread_mutex_t mutex = pthread_mutex_initializer;
Use mutex:
The consumer calls the pthread_mutex_lock function. If the mutex object is not locked, this function returns immediately. If the mutex object is locked, this function blocks the execution of this thread until the mutex is unlocked.
After each unlock, only one thread can unblocking and resume execution. Other Call threads will continue to block. The selected thread to remove blocking is unpredictable.
The consumer calls the pthread_mutex_unlock function to unlock the mutex object from the call thread. In the thread that locks the mutex, you must call this function to unlock the lock.
Mutex provides a solution to solve the competition condition, but it brings a new bug --Deadlock(Deadlock).
The so-called deadlock means that a thread is waiting for conditions that will never happen.
A simple deadlock: A thread locks its own locked mutex. In this case, the program performance depends on the mutex type:
Fast mutex-causes a deadlock.
Recursive exclusive mutex-no deadlock is caused. The same thread can safely lock the same locked mutex multiple times, but the number of locks will be recorded, this thread must also call the pthread_mutex_unlock of the corresponding number of times to truly unlock the mutex.
Error-checking mutex -- GNU/Linux considers this operation as a deadlock, but calls the pthread_mutex_lock function for the locked mutex. The function immediately returns the error code edeadlk.
The lock function of mutex is blocked. Sometimes you need a function that does not block to know whether mutex is locked. In this way, you can complete other work when the mutex is locked and check it later. The function is as follows:
Pthread_mutex_trylock
If the imported mutex has been locked by other threads, this function returns the error code ebusy. If it is not locked, this function locks the mutex and returns 0. This function will not be blocked.