栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

2022-07-01 多线程互斥锁的一个案例

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2022-07-01 多线程互斥锁的一个案例

前言

最近回答了一个C语言多线程的小问题.

大概有些初涉多线程编程的学习者,在未学到 “锁” 这个概念的时候就已经开始写多线程代码。

但有个问题,要先明白,对于没有任何规划的多线程,很容易得到与预想相别万里的结果。

因为逻辑变了,单线程是顺序逻辑,多线程是乱序逻辑,需要人为干涉规划执行顺序。

举例

下面是问题的叙述,在无锁情况(并非可无锁并发的数据结构)导致的乱序:

C语言多线程操作多函数冲突

问题遇到的现象和发生背景

通过移动光标的方式,用两个线程执行两个不同函数分别在某列输出不同的数字。由于线程并发,输出的结果不对

问题代码可以参考链接:C语言多线程操作多函数 冲突

程序调用两个线程,运行两个函数:fun1,fun2,这两个函数分别调用 gotoxy 函数,定位光标,然后打印字符。

单线程顺序执行没有问题,多线程有很大问题。

两个线程会乱序的定位光标,乱序打印,导致这样一种情况:A挪光标,还没打印,B打印了,随后A才打印,或者相反,总之不是想要的结果。

为了梳理程序流程,我们需要加锁,让光标移动和打印原子化。

OK,我们在光标移动前和打印后加锁。

现在的问题是,可以有很多地方加锁,具体放哪里?

答案是放在刚刚要定位光标之前,刚刚打印完毕。

这看似是废话,其实还有有一定道理的。

一旦一个进程持有锁,另外一个进程就要等,我可以粗糙的放在 gotoxy 函数之前和 printf 函数之后,没有问题,但是我们想想,gotoxy 内部的变量初始化及句柄获取要不要占时间,它们要占时间,但是和移动光标没有关系,完全可以先准备出来,等持有锁的线程释放后立刻定位光标。

一句话,先把能干的都干了,只等时机到来。多么哲学。

当然这只是一个最简单的用例,基本没有死锁的风险,也没有恶性数据竞争,属于入门的入门。

以下代码:
#include 
#include 
#include 

pthread_mutex_t m;

void gotoxy(short x, short y)
{
    COORD pos;
    HANDLE hOutput;
    pos.X = x;
    pos.Y = y;
    hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    pthread_mutex_lock(&m);
    SetConsoleCursorPosition(hOutput, pos);
}

void *fun1(void *unused)
{
    short t = 0;
    while (t < 20)
    {
        gotoxy(10, t++);
        printf("11");
        pthread_mutex_unlock(&m);
    }
    pthread_exit(NULL);
    return NULL;
}

void *fun2(void *unused)
{
    short t = 0;
    while (t < 20)
    {
        gotoxy(1, t++);
        printf("22");
        pthread_mutex_unlock(&m);
    }
    pthread_exit(NULL);
    return NULL;
}

int main()
{
    pthread_mutex_init(&m, NULL);

    pthread_t pthread1;
    pthread_t pthread2;

    pthread_create(&pthread1, NULL, &fun1, NULL);
    pthread_create(&pthread2, NULL, &fun2, NULL);

    pthread_join(pthread1, NULL);
    pthread_join(pthread2, NULL);

    pthread_mutex_destroy(&m);

    return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1001320.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号