Mutex of linux system programming

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

/* 定义互斥量 */
pthread_mutex_t mtx;
/* 互斥量属性 */
pthread_mutexattr_t mtx_attr;
/* 全局资源 */
int money;

void err_exit(const char *err_msg)
{
    
    
    printf("error:%s\n", err_msg);
    exit(1);
}

void *fun(void *arg)
{
    
    
    while(1)
    {
    
    
        printf("fun线程正在运行!!!\n");
    }
    
}

/* 线程函数 */
void *thread_fun(void *arg)
{
    
    
     while (1)
     {
    
    
         /* 加锁 */
         pthread_mutex_lock(&mtx);
         pthread_mutex_lock(&mtx);
         printf("子线程进入临界区查看money\n");
         if (money == 0)
         {
    
    
             money += 200;
             printf("子线程:money = %d\n", money);
         }
         /* 解锁 */
         pthread_mutex_unlock(&mtx);
         sleep(1);
     }
     return NULL;
}

int main(void)
{
    
    
     pthread_t tid,tid1;

     /* 初始化互斥量属性 */
     if (pthread_mutexattr_init(&mtx_attr) == -1)
         err_exit("pthread_mutexattr_init()");

    /* 设置互斥量属性 */
    if (pthread_mutexattr_settype(&mtx_attr, PTHREAD_MUTEX_NORMAL) == -1)
        err_exit("pthread_mutexattr_settype()");

     /* 初始化互斥量 */
     if (pthread_mutex_init(&mtx, &mtx_attr) == -1)
         err_exit("pthread_mutex_init()");

     /* 创建一个线程 */
     if (pthread_create(&tid, NULL, thread_fun, NULL)== -1)
         err_exit("pthread_create()");

       /* 创建一个线程 */
     if (pthread_create(&tid1, NULL, fun, NULL)== -1)
         err_exit("pthread_create()");

     money = 1000;
     while (1)
     {
    
    
         /* 加锁 */
         pthread_mutex_lock(&mtx);

         if (money > 0)
         {
    
    
             money -= 100;
             printf("主线程:money = %d\n", money);
         }
         printf("getpid() = %d\n",getpid());
         /* 解锁 */
         pthread_mutex_unlock(&mtx);
 
         sleep(1);
    }

     return 0;
}
/*
一.概述

互斥量是线程同步的一种机制,用来保护多线程的共享资源。
同一时刻,只允许一个线程对临界区进行访问。
互斥量的工作流程:创建一个互斥量,把这个互
斥量的加锁调用放在临界区的开始位置,解锁调用放
到临界区的结束位置。当内核优先把某个线程调度到
临界区的开始位置时,线程执行这个加锁调用,并进入
临界区对资源进行操作。此时其他线程再被内核调度到这
里的时候,由于该互斥量已被加锁状态,得不到锁会一直
阻塞在这里,导致其他线程不能进入临界区,直到刚刚那
个进入临界区的线程离开临界区并执行解锁调用。

二.函数接口

1.初始化互斥量
互斥量是一个pthread_mutex_t类型的变量。

1.1:用宏常量初始化:
1 pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
1.2:用函数初始化:

#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
mutex:互斥量结构指针
attr:互斥量的属性结构指针


2.设置互斥量属性
#include <pthread.h>
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
attr:互斥量的属性结构指针
type:PTHREAD_MUTEX_NORMAL(默认属性),PTHREAD_MUTEX_ERRORCHECK(会进行错误检查,速度比较慢),PTHREAD_MUTEX_RECURSIVE(递归锁)。对于递归锁,同一个线程对一个递归锁加锁多次,会有一个锁计数器,解锁的时候也需要解锁这个次数才能释放该互斥量。


3.加锁与解锁
#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);
参数都是互斥量指针。pthread_mutex_lock()得不到锁会阻塞,
int pthread_mutex_trylock()得不到锁会立即返回,并返回EBUSY错误。

还有一个pthread_mutex_timedlock()会根据时间来等待加锁,
如果这段时间得不到锁会返回ETIMEDOUT错误!

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

4.销毁互斥量
#include <pthread.h>
int pthread_mutex_destroy(pthread_mutex_t *mutex);
mutex:创建的互斥量指针
*/

/*
注意点:
(1)同一把锁,在一个线程当中,不能连续上锁多次(1次以上)
(2)上锁和解锁必须配套使用
(3)当一个线程当中把这把锁上锁了以后,另外一个线程对这把锁再上锁时就会不成功,必须要等到这把锁解锁/
*/

Guess you like

Origin blog.csdn.net/qq_38158479/article/details/114441227