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的这个特性。

目录
相关文章
|
7月前
|
C++
C++11 std::lock_guard 互斥锁
C++11 std::lock_guard 互斥锁
65 0
|
5月前
|
Python
Mutex
【7月更文挑战第2天】
28 2
|
7月前
|
存储 缓存 安全
C语言进程(第二章,wait,sleep,waitpid,pthread_mutex_lock,pthread_mutex_unlock)
C语言进程(第二章,wait,sleep,waitpid,pthread_mutex_lock,pthread_mutex_unlock)
143 0
C++11/14/17中提供的mutex系列区别
C++11/14/17中提供的mutex系列类型如下:
102 0
|
调度 C++
C++11之线程库(Thread、Mutex、atomic、lock_guard、同步)
C++11之线程库(Thread、Mutex、atomic、lock_guard、同步)
233 0
pthread_mutex_unlock()出错
pthread_mutex_unlock()出错
156 0
|
Linux API
pthread_mutex_init & 互斥锁pthread_mutex_t的使用
pthread_mutex_init l         头文件: #include l         函数原型: int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr); pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; l         函数作用: 该函数用于C函数的多线程编程中,互斥锁的初始化。
1951 0
|
C++
【C++ 语言】pthread_mutex_t 互斥锁
【C++ 语言】pthread_mutex_t 互斥锁
294 0
|
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 前几天写了一段示例代码,想说明一下可重入函数。
1394 0

热门文章

最新文章