欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 运维知识 > linux >内容正文

linux

linux线程同步之互斥锁——linux的关键区域

发布时间:2025/5/22 linux 70 豆豆
生活随笔 收集整理的这篇文章主要介绍了 linux线程同步之互斥锁——linux的关键区域 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

在windows中,为了让多个线程达到同步的目的,在对于全局变量等大家都要用的资源的使用上,通常得保证同时只能由一个线程在用,一个线程没有宣布对它的释放之前,不能够给其他线程使用这个变量。在windows里,我们可以用时EnterCriticalSection()和LeaveCriticalSection()函数.那么在linux里,有什么类似的机制呢?

 

这里介绍互斥锁。

1.申请一个互斥锁

pthread_mutex_t mutex; //申请一个互斥锁

你可以声明多个互斥量。

在声明该变量后,你需要调用pthread_mutex_init()来创建该变量。pthread_mutex_init的格式如下:

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

第一个参数,mutext,也就是你之前声明的那个互斥量,第二个参数为该互斥量的属性。属性定义如下:

互斥量分为下面三种:

l         快速型(PTHREAD_MUTEX_FAST_NP

)。这种类型也是默认的类型。该线程的行为正如上面所说的。

l         递归型(PTHREAD_MUTEX_RECURSIVE_NP

)。如果遇到我们上面所提到的死锁情况,同一线程循环给互斥量上锁,那么系统将会知道该上锁行为来自同一线程,那么就会同意线程给该互斥量上锁。

l         错误检测型(PTHREAD_MUTEX_ERRORCHECK_NP

)。如果该互斥量已经被上锁,那么后续的上锁将会失败而不会阻塞,pthread_mutex_lock()操作将会返回EDEADLK

 

可以通过函数

注意以下语句可以做到将一个互斥锁快速初始化为快速型。

pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;

 

2.销毁一个互斥锁

pthread_mutex_destroy()用于注销一个互斥锁,API定义如下:

 int pthread_mutex_destroy(pthread_mutex_t *mutex)

销毁一个互斥锁即意味着释放它所占用的资源,且要求锁当前处于开放状态。由于在Linux中,互斥锁并不占用任何资源,因此LinuxThreads中的pthread_mutex_destroy()除了检查锁状态以外(锁定状态则返回EBUSY)没有其他动作。

 

3.上锁(相当于windows下的EnterCriticalSection)

在创建该互斥量之后,你便可以使用它了。要得到互斥量,你需要调用下面的函数:

int pthread_mutex_lock(pthread_mutex_t *mutex);

该函数用来给互斥量上锁。互斥量一旦被上锁后,其他线程如果想给该互斥量上锁,那么就会阻塞在这个操作上。如果在此之前该互斥量已经被其他线程上锁,那么该操作将会一直阻塞在这个地方,直到获得该锁为止。

在得到互斥量后,你就可以进入关键代码区了。

 

4.解锁(相当于windows下的LeaveCriticalSection)

在操作完成后,你必须调用下面的函数来给互斥量解锁,也就是前面所说的释放。这样其他等待该锁的线程才有机会获得该锁,否则其他线程将会永远阻塞。

int pthread_mutex_unlock(pthread_mutex_t *mutex);

 

5.pthread_mutex_trylock

如果我们不想一直阻塞在这个地方,那么可以调用下面函数:

int pthread_mutex_trylock(pthread_mutex_t *mutex)

如果此时互斥量没有被上锁,那么pthread_mutex_trylock()将会返回0,并会对该互斥量上锁。如果互斥量已经被上锁,那么会立刻返回EBUSY

 

使用示例代码如下:

 

Code
#include <malloc.h>

#include 
<pthread.h>

struct job {

    
/* Link field for linked list. */

    
struct job* next;

    
/* Other fields describing work to be done */

};

/* A linked list of pending jobs. */

struct job* job_queue;

/* A mutex protecting job_queue. */

pthread_mutex_t job_queue_mutex 
= PTHREAD_MUTEX_INITIALIZER;

/* Process queued jobs until the queue is empty. */

void* thread_function (void* arg)

{

    
while (1) {

        
struct job* next_job;

        
/* Lock the mutex on the job queue. */

        pthread_mutex_lock (
&job_queue_mutex);

        
/* Now it’s safe to check if the queue is empty. */

        
if (job_queue == NULL)

            next_job 
= NULL;

        
else {

            
/* Get the next available job. */

            next_job 
= job_queue;

            
/* Remove this job from the list. */

            job_queue 
= job_queue->next;

        }

        
/* Unlock the mutex on the job queue because we’re done with the

        queue for now. 
*/

        pthread_mutex_unlock (
&job_queue_mutex);

        
/* Was the queue empty? If so, end the thread. */

        
if (next_job == NULL)

            
break;

        
/* Carry out the work. */

        process_job (next_job);

        
/* Clean up. */

        free (next_job);

    }

    
return NULL;

}

 

 

转载于:https://www.cnblogs.com/aicro/archive/2009/06/17/1505322.html

总结

以上是生活随笔为你收集整理的linux线程同步之互斥锁——linux的关键区域的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。