【Linux系统编程】32.线程同步、锁的使用、互斥锁管理

目录

线程同步

锁的使用

注意事项

pthread_mutex_init

注意

参数mutex

参数attr

返回值

动态初始化

静态初始化

pthread_mutex_destroy

参数mutex

返回值

pthread_mutex_lock

参数mutex

返回值

pthread_mutex_unlock

参数mutex

返回值

pthread_mutex_trylock

参数mutex

返回值

测试代码1

测试结果

线程同步

        线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据一致性,不能调用该功能。

        协调同步,对公共区域数据按序访问。防止数据混乱,产生与时间有关的错误。

锁的使用

        建议锁。对公共数据进行保护。所有线程应该在访问公共数据前先拿锁再访问。但锁本身不具备强制性。

注意事项

  • 尽量保证锁的粒度,越小越好。访问共享数据前,加锁。访问结束,立即解锁。

  • 互斥锁本质是结构体。

pthread_mutex_init

初始化一个互斥锁(互斥量),初值可看作1。

man pthread_mutex_init

注意

 

对于这个没有手册页条目问题,直接安装manpages-posix-dev即可。  

sudo apt-get install manpages-posix-dev

参数mutex

       传出参数,调用时传&mutex。

       restrict关键字:只用于限制指针,告诉编译器,所有修改该指针指向内存中内容的操作,只能通过本指针完成。不能通过除本指针以外的其他变量或指针修改。

参数attr

互斥量属性,是一个传入参数,通常传NULL,选用默认属性(线程间共享)。

返回值

成功:0

失败:错误号

动态初始化

pthread_mutex_t mutex;
pthread_mutex_init(&mutex,NULL);	//动态初始化

静态初始化

pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;	//静态初始化

pthread_mutex_destroy

销毁一个互斥锁。

man pthread_mutex_destroy

参数mutex

传出参数,调用时传&mutex。

返回值

成功:0

失败:错误号

pthread_mutex_lock

加锁。可理解为将mutex--(或 -1),操作后mutex的值为 0。

man pthread_mutex_lock

参数mutex

传出参数,调用时传&mutex。

返回值

成功:0

失败:错误号

pthread_mutex_unlock

解锁。可理解为将mutex++(或+1),操作后mutex的值为1。

man pthread_mutex_unlock

参数mutex

传出参数,调用时传&mutex。

返回值

成功:0

失败:错误号

pthread_mutex_trylock

尝试加锁。

man pthread_mutex_trylock

参数mutex

传出参数,调用时传&mutex。

返回值

成功:0

失败:错误号,同时设置错误EBUSY。

测试代码1

借助互斥锁管理共享数据实现同步。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>

pthread_mutex_t Suo; //锁
int flag;

void *HuiDiao_HanShu(void *arg)
{
    srand(time(NULL));
    while (1)
    {
        flag = pthread_mutex_lock(&Suo); //加锁
        if (flag != 0)
        {
            printf("加锁错误:%s\n", strerror(flag));
            exit(1);
        }
        printf("你好,");
        sleep(rand() % 3);
        printf("世界。\n");
        flag = pthread_mutex_unlock(&Suo); //解锁
        if (flag != 0)
        {
            printf("解锁错误:%s\n", strerror(flag));
            exit(1);
        }
        sleep(rand() % 3);
    }
    return NULL;
}

int main(int argc, char *argv[])
{
    pthread_t ZiXianCheng_ID; //子线程ID
    void *num = NULL;
    srand(time(NULL));

    flag = pthread_mutex_init(&Suo, NULL); //初始化锁
    if (flag != 0)
    {
        printf("初始化锁错误:%s\n", strerror(flag));
        exit(1);
    }

    flag = pthread_create(&ZiXianCheng_ID, NULL, HuiDiao_HanShu, NULL); //创建子线程
    if (flag != 0)
    {
        printf("创建子线程错误:%s\n", strerror(flag));
        exit(1);
    }

    while (1)
    {
        flag = pthread_mutex_lock(&Suo); //加锁
        if (flag != 0)
        {
            printf("加锁错误:%s\n", strerror(flag));
            exit(1);
        }
        printf("NiHao,");
        sleep(rand() % 3);
        printf("ShiJie。\n");
        flag = pthread_mutex_unlock(&Suo); //解锁
        if (flag != 0)
        {
            printf("解锁错误:%s\n", strerror(flag));
            exit(1);
        }
        sleep(rand() % 3);
    }

    printf("开始回收子线程!\n");
    flag = pthread_join(ZiXianCheng_ID, NULL);
    if (flag != 0)
    {
        printf("回收子线程错误:%s\n", strerror(flag));
        exit(1);
    }
    printf("回收子线程完成!\n");

    flag = pthread_mutex_destroy(&Suo); //销毁锁
    if (flag != 0)
    {
        printf("销毁锁错误:%s\n", strerror(flag));
        exit(1);
    }

    pthread_exit(NULL);

    return 0;
}

测试结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

因心,三人水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值