pthread_mutex_lock()的属性介绍

pthread_mutex_lock

pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

描述 pthread_mutex_lock()函数锁住由mutex指定的mutex 对象。如果mutex已经被锁住,调用这个函数的线程阻塞直到mutex可用为止。这跟函数返回的时候参数mutex指定的mutex对象变成锁住状态, 同时该函数的调用线程成为该mutex对象的拥有者。

如果mutex 对象的type是 PTHREAD_MUTEX_NORMAL,不进行deadlock detection(死锁检测)。企图进行relock 这个mutex会导致deadlock. 如果一个线程对未加锁的或已经unlock的mutex对象进行unlock操作,结果是不未知的。

如果mutex类型是 PTHREAD_MUTEX_ERRORCHECK,那么将进行错误检查。如果一个线程企图对一个已经锁住的mutex进行relock,将返回一个错 误。如果一个线程对未加锁的或已经unlock的mutex对象进行unlock操作,将返回一个错误。

如果mutex类型是 PTHREAD_MUTEX_RECURSIVE,mutex会有一个锁住次数(lock count)的概念。当一个线程成功地第一次锁住一个mutex的时候,锁住次数(lock count)被设置为1,每一次一个线程unlock这个mutex的时候,锁住次数(lock count)就减1。当锁住次数(lock count)减少为0的时候,其他线程就能获得该mutex锁了。如果一个线程对未加锁的或已经unlock的mutex对象进行unlock操作,将返 回一个错误。

如果mutex类型是 PTHREAD_MUTEX_DEFAULT,企图递归的获取这个mutex的锁的结果是不确定的。unlock一个不是被调用线程锁住的mutex的结 果也是不确定的。企图unlock一个未被锁住的mutex导致不确定的结果。

pthread_mutex_trylock()调用在参数mutex指定的mutex对象当前被锁住的时候立即返回,除此之外,pthread_mutex_trylock()跟pthread_mutex_lock()功能完全一样。

pthread_mutex_unlock()函数释放有参数mutex指定的mutex对象的锁。如果被释放取决于该Mutex对象的类型属性。如果有多个线程为了获得该mutex锁阻塞,调用pthread_mutex_unlock()将是该mutex可用,一定的调度策略将被用来决定哪个线程可以获得该mutex锁。(在mutex类型为PTHREAD_MUTEX_RECURSIVE 的情况下,只有当lock count 减为0并且调用线程在该mutex上已经没有锁的时候)(翻译到这里,才觉得我的这个锁概念是多么模糊)
如果一个线程在等待一个mutex锁得时候收到了一个signal,那么在从signal handler返回的时候,该线程继续等待该mutex锁,就像这个线程没有被中断一样。

返回值成功

pthread_mutex_lock() 和 pthread_mutex_unlock() 返回0,否则返回一个错误的提示码

pthread_mutex_trylock() 在成功获得了一个mutex的锁后返回0,否则返回一个错误提示码错误

pthread_mutex_lock() 和 pthread_mutex_unlock()失败的时候 [EINVAL] mutex在生成的时候,它的protocol属性的值是 PTHREAD_PRIO_PROTECT,同时调用线程的优先级(priority)比该mutex的当前prority上限高

pthread_mutex_trylock() 函数在一下情况会失败:

[EBUSY] The mutex could not be acquired because it was already locked. mutex已经被锁住的时候无法再获取锁

The pthread_mutex_lock(), pthread_mutex_trylock() and pthread_mutex_unlock() functions may fail if:

[EINVAL] mutex指向的mutex未被初始化

[EAGAIN] Mutex的lock count(锁数量)已经超过 递归索的最大值,无法再获得该mutex锁

pthread_mutex_lock() 函数在一下情况下会失败:

[EDEADLK] 当前线程已经获得该mutex锁

pthread_mutex_unlock() 函数在以下情况下会失败:

[EPERM] 当前线程不是该mutex锁的拥有者 所有的这些函数的错误返回值都不会是[EINTR]

互斥锁

互斥锁用来保证一段时间内只有一个线程在执行一段代码。必要性显而易见:假设各个线程向同一个文件顺序写入数据,最后得到的结果一定是灾难性的。

我们先看下面一段代码。这是一个读/写程序,它们公用一个缓冲区,并且我们假定一个缓冲区只能保存一条信息。即缓冲区只有两个状态:有信息或没有信息。

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;

/* 定义延迟时间*/

delay.tv_sec = 2;

delay.tv_nec = 0;

/* 用默认属性初始化一个互斥锁对象*/

pthread_mutex_init (&mutex,NULL);

pthread_create(&reader, pthread_attr_default, (void *)&reader_function), NULL);

writer_function( );

}

void writer_function (void){

while(1){

/* 锁定互斥锁*/

pthread_mutex_lock (&mutex);

if (buffer_has_item==0){

buffer=make_new_item( );

buffer_has_item=1;

}

/* 打开互斥锁*/

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);

}

}

这里声明了互斥锁变量mutex,结构pthread_mutex_t为不公开的数据类型,其中包含一个系统分配的属性对象。函数 pthread_mutex_init用来生成一个互斥锁。NULL参数表明使用默认属性。如果需要声明特定属性的互斥锁,须调用函数 pthread_mutexattr_init。函数pthread_mutexattr_setpshared和函数 pthread_mutexattr_settype用来设置互斥锁属性。前一个函数设置属性pshared,它有两个取 值,PTHREAD_PROCESS_PRIVATE和PTHREAD_PROCESS_SHARED。前者用来不同进程中的线程同步,后者用于同步本进
程的不同线程。在上面的例子中,我们使用的是默认属性PTHREAD_PROCESS_ PRIVATE。后者用来设置互斥锁类型,可选的类型有PTHREAD_MUTEX_NORMAL、PTHREAD_MUTEX_ERRORCHECK、 PTHREAD_MUTEX_RECURSIVE和PTHREAD _MUTEX_DEFAULT。它们分别定义了不同的上所、解锁机制,一般情况下,选用最后一个默认属性。

pthread_mutex_lock声明开始用互斥锁上锁,此后的代码直至调用pthread_mutex_unlock为止,均被上锁,即同一时间只 能被一个线程调用执行。当一个线程执行到pthread_mutex_lock处时,如果该锁此时被另一个线程使用,那此线程被阻塞,即程序将等待到另一 个线程释放此互斥锁。在上面的例子中,我们使用了pthread_delay_np函数,让线程睡眠一段时间,就是为了防止一个线程始终占据此函数。

上面的例子非常简单,就不再介绍了,需要提出的是在使用互斥锁的过程中很有可能会出现死锁:两个线程试图同时占用两个资源,并按不同的次序锁定相应的互 斥锁,例如两个线程都需要锁定互斥锁1和互斥锁2,a线程先锁定互斥锁1,b线程先锁定互斥锁2,这时就出现了死锁。此时我们可以使用函数 pthread_mutex_trylock,它是函数pthread_mutex_lock的非阻塞版本,当它发现死锁不可避免时,它会返回相应的信 息,程序员可以针对死锁做出相应的处理。另外不同的互斥锁类型对死锁的处理不一样,但最主要的还是要程序员自己在程序设计注意这一点。

时间: 2024-10-18 11:56:04

pthread_mutex_lock()的属性介绍的相关文章

CSS float 浮动属性介绍

float属性:定义元素朝哪个方向浮动. 1.页面标准文档流.浮动层.float属性 1.1 文档流 HTML页面的标准文档流(默认布局)是:从上到下,从左到右,遇块(块级元素)换行. 1.2 浮动层 浮动层:给元素的float属性赋值后,就是脱离文档流,进行左右浮动,紧贴着父元素(默认为body文本区域)的左右边框. 而此浮动元素在文档流空出的位置,由后续的(非浮动)元素填充上去:块级元素直接填充上去,若跟浮动元素的范围发生重叠,浮动元素覆盖块级元素.内联元素:有空隙就插入. 1.3 floa

IOS的UITextField,UIButton,UIWebView的一些属性介绍和IOS图片资源的使用技巧

有时候UI给开发的资源跟实际的frame不一致,这个时候我们就要去拉伸图片 UIImage* image = [[UIImage imageNamed:@"text_field_bg.png"] stretchableImageWithLeftCapWidth:20 topCapHeight:0]; //stretchableImageWithLeftCapWidth使图片有拉伸效果 UITextField的属性介绍: UITextField* field = [[UITextFiel

javascript继承—prototype属性介绍(2)

js里每一个function都有一个prototype属性,而每一个实例都有constructor属性,并且每一个function的prototype都有一个constructor属性,这个属性会指向自身.这会形成一个非常有意思的链式结构.举例如下: function Person(){ this.name =12; } console.log(Person.prototype); console.log(Person.prototype.constructor);//输出Person,指向自身

pthread_mutex_lock/unlock(1)

我们来考察下pthread中锁的实现. 首先看下初始化宏:PTHREAD_MUTEX_INITIALIZER. # define PTHREAD_MUTEX_INITIALIZER { { 0, 0, 0, 0, 0, __PTHREAD_SPINS, { 0, 0 } } } /* Data structures for mutex handling. The structure of the attribute type is not exposed on purpose. *//*删减了3

RelativeLayout经常使用属性介绍

以下介绍一下RelativeLayout用到的一些重要的属性: 第一类:属性值为true或false android:layout_centerHrizontal                                           水平居中 android:layout_centerVertical                                            垂直居中 android:layout_centerInparent              

Android TableLayout 常用的属性介绍及演示

TableLayout经常用的属性是: 1.android:collapseColumns:以第0行为序,隐藏指定的列:把android:collapseColumns=0,2 意思是把第0和第2列隐藏 2.android:shrinkColumns:以第0行为序,自动延伸指定的列填充可用部分:当LayoutRow里面的控件还没有布满布局 时,shrinkColumns不起作用,设置了shrinkColumns=0,1,2,布局完全没有改变,因为LayoutRow里面还剩足够的空 间.当Layo

布局的一些属性介绍

DIV+CSS布局中主要CSS属性介绍: Float: Float属性是DIV+CSS布局中最基本也是最常用的属性,用于实现多列功能,我们知道<div>标签默认一行只能显示一个,而使用Float属性可以实现一行显示多个div的功能,最直接解释方法就是能实现表格布局的多列功能. Margin: Margin属性用于设置两个元素之间的距离. Padding: Padding属性用于设置一个元素的边框与其内容的距离. Clear: 使用Float属性设置一行有多个DIV后(多列),最好在下一行开始之

ios 开发日记 13-剖析网易新闻标签栏视图切换(addChildViewController属性介绍)

iOS开发 剖析网易新闻标签栏视图切换(addChildViewController属性介绍) 时间 2014-06-25 21:45:21  CSDN博客 原文  http://blog.csdn.net/hmt20130412/article/details/34523235 主题 网易iOS开发 本来只是打算介绍一下addChildViewController这个方法的,正好今天朋友去换工作面试问到网易新闻标签栏效果的实现,就结合它,用个小Demo实例介绍一下:(具体解释都写在了Demo里

SlidingMenu 常用属性介绍

SlidingMenu 常用属性介绍:menu.setMode(SlidingMenu.LEFT);//设置左滑菜单menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);//设置滑动的屏幕范围,该设置为全屏区域都可以滑动menu.setShadowDrawable(R.drawable.shadow);//设置阴影图片menu.setShadowWidthRes(R.dimen.shadow_width);//设置阴影图片的宽度menu