pthread_mutex_lock的thread特性

简介:

pthread_mutex_lock的thread特性

作者:gfree.wind@gmail.com
博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net
微博:weibo.com/glinuxer
QQ技术群:4367710

前几天写了一段示例代码,想说明一下可重入函数。所以我在一个函数中使用了pthread_mutex_lock,来说明一旦函数使用了锁,就变成了不可重入的函数。

#include 
#include 

#include 
#include 
#include 
#include 

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

static const char * const caller[2] = {"main", "signal handler"};
static volatile int signal_handler_exit = 0;

static void hold_mutex(int c)
{
        printf("enter hold_mutex [caller %s]\n", caller[c]);

        pthread_mutex_lock(&mutex);

        /* 保证信号函数退出前, main线程始终拥有锁 */
        while (!signal_handler_exit && c != 1) {
                sleep(5);
        }

        pthread_mutex_unlock(&mutex);

        printf("leave hold_mutex [caller %s]\n", caller[c]);
}

static void signal_handler(int signum)
{
        hold_mutex(1);
        signal_handler_exit = 1;
}
int main()
{
        signal(SIGALRM, signal_handler);

        alarm(3);

        hold_mutex(0);

        return 0;
} .h>.h>.h>.h>.h>

上面代码很简单,main函数调用hold_mutex来持有锁。hold_mutex直到SIGALRM信号处理函数返回后,才会释放锁和退出。同时,main利用alarm,在3秒后可以收到信号SIGALRM,而SIGALRM的信号处理函数也会调用hold_mutex。

这就保证了,在main线程持有锁的过程中,通过信号处理机制,再次进入hold_mutex,来造成“死锁”的场景。用以说明hold_mutex是不可重入的。

可是运行结果让我很意外。。。

[fgao@fgao test]#./a.out
enter hold_mutex [caller main]
enter hold_mutex [caller signal handler]
leave hold_mutex [caller signal handler]
leave hold_mutex [caller main]
[fgao@fgao test]# 

这是怎么回事呢?为什么在main拿到锁以后,信号处理函数还是可以拿到锁呢?我决定在这样试一下,直接在hold_mutex中再次拿锁。 代码变成了下面这样:

#include 
#include 

#include 
#include 
#include 
#include 

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

static void hold_mutex(int c)
{
        if (c == 0) {
                return;
        }


        printf("enter hold_mutex [caller %d]\n", c);

        pthread_mutex_lock(&mutex);

        hold_mutex(c-1);

        pthread_mutex_unlock(&mutex);

        printf("leave hold_mutex [caller %d]\n", c);
}

int main()
{
        hold_mutex(3);

        return 0;
} .h>.h>.h>.h>.h>

执行结果如下:

[fgao@fgao test]#./a.out
enter hold_mutex [caller 3]
enter hold_mutex [caller 2]
enter hold_mutex [caller 1]
leave hold_mutex [caller 1]
leave hold_mutex [caller 2]
leave hold_mutex [caller 3]
[fgao@fgao test]# 

看到这样的结果,我首先想到难道pthread_mutex_lock是递归锁?但仔细想了想,又推翻了这个想法。递归锁是一种特殊的锁,不大可能会作为默认行为。

当我盯着pthread_mutex_lock这个名字,pthread这个关键字给我带来了提示。这个锁是否是跟线程相关呢?当该线程拥有了该锁后,可以继续上锁呢?

重读了一遍manual手册,证实了自己的想法。 The mutex object referenced by mutex shall be locked by calling pthreadmutexlock(). If the mutex is already locked, the calling thread shall block until the mutex becomes available. This operation shall return with the mutex object referenced by mutex in the locked state with the calling thread as its owner.

最后一句与我猜测的结果一样。虽然猜中了这个结果,但是我却没有一点兴奋,因为做Linux程序员已经有六、七年了,居然刚发现pthread_mutex_lock的这个特性。

目录
相关文章
|
Linux 程序员
pthread_mutex_lock的thread特性
pthread_mutex_lock的thread特性 作者:gfree.wind@gmail.com 博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net 微博:weibo.com/glinuxer QQ技术群:4367710 前几天写了一段示例代码,想说明一下可重入函数。
1401 0
|
调度 C++
C++11之线程库(Thread、Mutex、atomic、lock_guard、同步)
C++11之线程库(Thread、Mutex、atomic、lock_guard、同步)
257 0
|
Linux 调度 程序员
|
API
Spin lock 与mutex 的区别--2011.01.06
POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API。线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段,其中最典型的应用就是用Pthreads提供的锁机制(lock)来对多个线程之间共 享的临界区(Critical Section)进行保护(另一种常用的同步机制是barrier)。
1143 0
通用线程:POSIX 线程详解pthread_mutex_lock
POSIX 线程是提高代码响应和性能的有力手段。在此三部分系列文章的第二篇中,DanielRobbins 将说明,如何使用被称为互斥对象的灵巧小玩意,来保护线程代码中共享数据结构的完整性。
983 0
C++11/14/17中提供的mutex系列区别
C++11/14/17中提供的mutex系列类型如下:
125 0
|
9月前
|
存储 缓存 安全
C语言进程(第二章,wait,sleep,waitpid,pthread_mutex_lock,pthread_mutex_unlock)
C语言进程(第二章,wait,sleep,waitpid,pthread_mutex_lock,pthread_mutex_unlock)
166 0
|
C++
boost库中thread多线程详解2——mutex与lock
1. mutex对象类 mutex类主要有两种:独占式与共享式的互斥量。▲ 独占式互斥量:mutex: 独占式的互斥量,是最简单最常用的一种互斥量类型try_mutex: 它是mutex的同义词,为了与兼容以前的版本而提供timed_mutex: 它也是独占式的互斥量,但提供超时锁定功能▲ 递归式...
1433 0
pthread_mutex_unlock()出错
pthread_mutex_unlock()出错
167 0

热门文章

最新文章