Linux_5.2_线程互斥



 (1) 线程互斥


Windows与Linux线程同步互斥

对象操作Linux Pthread APIWindows SDK 库对应 API
线程创建pthread_createCreateThread
退出pthread_exitThreadExit
等待pthread_joinWaitForSingleObject
互斥锁创建pthread_mutex_initCreateMutex
销毁pthread_mutex_destroyCloseHandle
加锁pthread_mutex_lockWaitForSingleObject
解锁pthread_mutex_unlockReleaseMutex
条件创建pthread_cond_initCreateEvent
销毁pthread_cond_destroyCloseHandle
触发pthread_cond_signalSetEvent
广播pthread_cond_broadcastSetEvent / ResetEvent
等待pthread_cond_wait / pthread_cond_timedwaitSingleObjectAndWait


pthread_mutex_init 函数原型:

  pthread_mutex_init 初始化一个互斥锁

所需头文件

#include <pthread.h>

函数说明

初始化互斥量

函数原型

int pthread_mutex_init(pthread_mutex_t *restrict mutex, 

                                    const pthread_mutexattr_t *restrict attr)

函数传入值

 mutex

指向要初始化的互斥锁的指针


 attr

指向属性对象的指针,该属性对象定义要初始化的互斥锁的属性

如果该指针为 NULL,则使用默认的属性。

默认使用PTHREAD_MUTEX_DEFAULT

                   合法的类型属性值有:

                   PTHREAD_MUTEX_NORMAL;

                   PTHREAD_MUTEX_ERRORCHECK;

                   PTHREAD_MUTEX_RECURSIVE;

                   PTHREAD_MUTEX_DEFAULT。


函数返回值

成功:0

出错:返回错误码


错误代码

EAGAIN:系统缺少足够的资源去初始化其他的互斥量

ENOMEM:内存不足去初始化互斥量

EPERM:调用者没有执行该操作的权限



类型说明:

PTHREAD_MUTEX_NORMAL   快速互斥锁

这种类型的互斥锁不会自动检测死锁。如果一个线程试图对一个互斥锁重复锁定,将会引起这个线程的死锁。如果试图解锁一个由别的线程锁定的互斥锁会引发不可预料的结果。如果一个线程试图解锁已经被解锁的互斥锁也会引发不可预料的结果。

 

PTHREAD_MUTEX_ERRORCHECK  检错互斥锁

这种类型的互斥锁会自动检测死锁。如果一个线程试图对一个互斥锁重复锁定,将会返回一个错误代码。如果试图解锁一个由别的线程锁定的互斥锁将会返回一个错误代码。如果一个线程试图解锁已经被解锁的互斥锁也将会返回一个错误代码。

 

PTHREAD_MUTEX_RECURSIVE  递归互斥锁

如果一个线程对这种类型的互斥锁重复上锁,不会引起死锁,一个线程对这类互斥锁的多次重复上锁必须由这个线程来重复相同数量的解锁,这样才能解开这个互斥锁,别的线程才能得到这个互斥锁。如果试图解锁一个由别的线程锁定的互斥锁将会返回一个错误代码。如果一个线程试图解锁已经被解锁的互斥锁也将会返回一个错误代码。这种类型的互斥锁只能是进程私有的(作用域属性为PTHREAD_PROCESS_PRIVATE)。

 

PTHREAD_MUTEX_DEFAULT   快速互斥锁

这种类型的互斥锁不会自动检测死锁。如果一个线程试图对一个互斥锁重复锁定,将会引起不可预料的结果。如果试图解锁一个由别的线程锁定的互斥锁会引发不可预料的结果。如果一个线程试图解锁已经被解锁的互斥锁也会引发不可预料的结果。POSIX标准规定,对于某一具体的实现,可以把这种类型的互斥锁定义为其他类型的互斥锁。

 

    互斥锁可以分为快速互斥锁、递归互斥锁和检错互斥锁。这三种锁的区别主要在于其他未占有互斥锁的线程在希望得到互斥锁时的是否需要阻塞等待。快速锁是指调用线程会阻塞直至拥有互斥锁的线程解锁为止。递归互斥锁能够成功地返回并且增加调用线程在互斥上加锁的次数,而检错互斥锁则为快速互斥锁的非阻塞版本,它会立即返回并返回一个错误信息。




pthread_mutex_destroy 函数原型:

  pthread_mutex_destroy 销毁一个互斥量

所需头文件

#include <pthread.h>

函数说明

 释放对互斥变量分配的资源

函数原型

 int pthread_mutex_destroy(pthread_mutex_t *mutex)

函数传入值

   mutex  

要释放的互斥量参数





函数返回值

成功:返回0

失败:返回错误码

错误代码

EBUSY:检测到企图摧毁被锁定的通过mutex属性引用的目标 或者 被另一线程引用

EINVAL: 由mutex指定的值失效


pthread_mutex_lock函数原型:

  pthread_mutex_lock 锁住一个互斥量

所需头文件

#include <pthread.h>

函数说明

 如果已经锁定了互斥对象,调用线程将阻塞,直到互斥锁解锁

函数原型

 int pthread_mutex_lock(pthread_mutex_t *mutex)

函数传入值

   mutex  

 指向需要获取互斥锁并给其上锁的结构的指针。





函数返回值

成功:返回0

失败:返回错误码

错误代码

EINVAL:互斥锁是由协议属性PTHREAD_PRIO_PROTECT指定

              并且调用线程的优先级比mutex的当前优先级上限高
              mutex指定的值不会引用一个初始化的互斥对象。
EAGAIN:由于超过递归锁的最大值导致互斥锁不能获取到
EDEADLK:当前线程已经拥有互斥锁



pthread_mutex_trylock函数原型:

  pthread_mutex_trylock 锁住一个互斥量

所需头文件

#include <pthread.h>

函数说明

 试图根据mutex为其上互斥锁,如果其已经被上锁,则不会阻塞线程。

函数原型

 int pthread_mutex_trylock(pthread_mutex_t *mutex)

函数传入值

   mutex  

指向需要获取互斥锁并给其上锁的结构的指针。





函数返回值

成功:返回0

失败:返回错误码

错误代码

EINVAL:互斥锁是由协议属性PTHREAD_PRIO_PROTECT指定

              并且调用线程的优先级比mutex的当前优先级上限高
              mutex指定的值不会引用一个初始化的互斥对象。
EAGAIN:由于超过递归锁的最大值导致互斥锁不能获取到
EDEADLK:当前线程已经拥有互斥锁
EBUSY:mutex不能被获取,由于它已经被锁

pthread_mutex_unlock函数原型:

  pthread_mutex_unlock 锁住一个互斥量

所需头文件

#include <pthread.h>

函数说明

根据mutex解锁互斥锁

函数原型

 int pthread_mutex_unlock(pthread_mutex_t *mutex)

函数传入值

   mutex  

指向需要释放互斥锁并给其解锁的结构的指针。





函数返回值

成功:返回0

失败:返回错误码

错误代码

EINVAL:mutex指定的值不会引用一个初始化的互斥对象。

EAGAIN:由于超过递归锁的最大值导致互斥锁不能获取到
EPERM:当前线程内有自己的互斥锁



实验用例:

#include <stdio.h>  
#include <pthread.h>
  
pthread_mutex_t mutex ;  
void *print_msg(void *arg){  
        int i=0;  
        pthread_mutex_lock(&mutex);  
        for(i=0;i<15;i++){  
                printf("output : %d\n",i);  
                usleep(100);  
        }  
        pthread_mutex_unlock(&mutex);  
}  
int main(int argc,char** argv){  
        pthread_t id1;  
        pthread_t id2;  
        pthread_mutex_init(&mutex,NULL);  
        pthread_create(&id1,NULL,print_msg,NULL);  
        pthread_create(&id2,NULL,print_msg,NULL);  
        pthread_join(id1,NULL);  
        pthread_join(id2,NULL);  
        pthread_mutex_destroy(&mutex);  
        return 1; 
} 










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值