UNIX(编程-线程处理):07---互斥量与互斥量锁(pthread_mutex_t)

一、互斥量概念

二、互斥变量(pthread_mutex_t)

  • 互斥量数据类型:pthread_mutex_t

三、互斥变量的初始化与释放

使用互斥变量之前需要对其进行初始化,根据互斥变量类型不同,分为:

①静态初始化:

  • 方式一:可以把它设置为常量PTHREAD_MUTEX_INITIALIZER
  • 方式二:通过pthread_mutex_init函数

②动态初始化:(例如:通过malloc函数申请内存的)

  • 只能通过pthread_mutex_init
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destory(pthread_mutex_t *mutex);
// 返回值:成功返回0,否则返回错误编号

pthread_mutex_init:对互斥量进行初始化

  • 参数1: 需要初始化互斥量
  • 参数2:初始化时互斥量的属性。如果使用默认属性,此处填NULL

pthread_mutex_destory:如果动态分配互斥量(如使用到malloc),那么释放内存前需要调用此函数

  • 参数:释放的互斥量

四、互斥量的加锁与解锁

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);

// 返回值:成功返回0,否则返回错误编号
  • pthread_mutex_lock:对互斥量进行加锁。如果互斥量已经上锁,调用线程将阻塞到互斥量被解锁
  • pthread_mutex_unlock:对互斥量进行解锁
  • pthead_mutex_trylock:对互斥量进行尝试加锁(非阻塞)。如果互斥量处于未加锁状态,那么pthead_mutex_trylock就会锁住这个互斥量;如果此锁处于加锁状态,那么pthead_mutex_trylock就出错返回EBUSY,并且不会阻塞

例如去食堂吃饭:如果食堂人太多(加锁),pthread_mutex_lock就会排队等待(阻塞);pthead_mutex_trylock是去食堂尝试(try)一下,如果人多就不排队(不阻塞)直接退出

五、演示案例

struct foo {
    int f_count;
    pthread_mutex_t f_lock;
    int f_id;
};

struct foo *foo_alloc(int id)
{
    struct foo *fp;

    if ((fp == malloc(sizeof(struct foo))) != NULL) {
        fp->f_count = 1;
        fp->f_id = id;
        if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
            free(fp);
            fp = NULL;
        }
    }

    return fp;
}

void foo_hold(struct foo *fp)
{
    pthread_mutex_lock(&fp->f_lock);
    fp->f_count++;
    pthread_mutex_unlock(&fp->f_lock);
}

void foo_rele(struct foo *fp)
{
    pthread_mutex_lock(&fp->f_lock);
    if (--fp->f_count == 0) {
        pthread_mutex_unlock(&fp->f_lock);
        pthread_mutex_destory(&fp->f_lock);
        free(fp);
    } else {
        pthread_mutex_unlock(&fp->f_lock);
    }
}

六、超时互斥锁(pthread_mutex_timedlock

#include <pthread.h>
#include <time.h>
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,const struct timespec *restrict tsptr);

// 返回值:成功返回0,否则返回错误编号.
  • 功能:当线程试图获取一个已加锁的互斥量时,pthread_mutex_timedlock允许绑定线程阻塞时间
  • 特点:pthread_mutex_timedlock与pthread_mutex_lock是基本等价的,但是在达到超时时间值时,pthread_mutex_timedlock不会对互斥量进行加锁,而是返回错误码ETIMEDOUT

注意:

  • 演示案例:下面给出了pthread_mutex_timedlock避免永久阻塞
#include <pthread.h>

int main(void)
{
    int err;
    struct timespec tout;
    struct tm *tmp;
    char buf[64];

    pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_lock(&lock);
    printf("mutex is locked\n");
    clock_gettime(CLOCK_REALTIME, &tout);
    tmp = localtime(&tout.tv_sec);
    strftime(buf, sizeof(buf), "%r", tmp);
    printf("current time is %s\n", buf);
    tout.tv_sec += 10; /* 10 seconds from now */
    
    /* caution: this could lead to deadlock */
    err = pthread_mutex_timedlock(&lock, &tout);
    clock_gettime(CLOCK_REALTIME, &tout);
    tmp = localtime(&tout.tv_sec);
    strftime(buf, sizeof(buf), "%r", tmp);
    printf("the time is now %s\n", buf);
    if (err == 0)
        printf("mutex locked again!\n");
    else
        printf("can’t lock mutex again: %s\n", strerror(err));
    exit(0);
}

运行结果

猜你喜欢

转载自blog.csdn.net/qq_41453285/article/details/89318860
今日推荐