多线程场景下设置代码段属于某特定线程

使用场景:一个线程完成一个任务需要循环访问某函数3次,且在这3次之间不允许其他线程执行该函数

解释:  某函数会被多个线程调用,但是获取到函数使用权的线程会多次调用该函数且在多次调用期间不允许其他线程执行该函数

核心代码实现:

std::mutex mAcquireBufferMutex;
std::mutex mApplicantsMutex;
std::condition_variable mAcquireBufferCond;

static std::string caller(""); // 标记当前的占用者是谁

void run(std::string myName,bool last) // last表示这一次调用是不是该线程最后一次使用该代码段
{
    std::unique_lock <std::mutex> lock(mAcquireBufferMutex);
    if(caller != std::string("")){
        while(caller != myName){
            mAcquireBufferCond.wait(lock);

            if(caller == std::string("")){
                caller = myName;
                break;
            }
        }
    }else{
        caller = myName;
    }
    
    /*
        run函数真正需要执行的部分
    */
    
    if(last){
        caller = std::string(""); // 占用结束把标记量设为初始值
        mAcquireBufferCond.notify_one();
    }
}

 

可执行代码:

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <string>
#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <unistd.h>
using namespace std;

void run(std::string myName,bool last,int number);
void func1();
void func2();
void func3();

static std::string caller("");

std::mutex mAcquireBufferMutex;
std::mutex mApplicantsMutex;
std::condition_variable mAcquireBufferCond;


void run(std::string myName,bool last,int number)
{
    std::unique_lock <std::mutex> lock(mAcquireBufferMutex);
    if(caller != std::string("")){
        while(caller != myName){
            cout << myName.c_str() << "  wait,number:"<< number << endl;
            mAcquireBufferCond.wait(lock);
            // std::unique_lock <std::mutex> lock(mApplicantsMutex);     如果使用notify_all();的话需要加锁再访问下面这个if判断
            if(caller == std::string("")){
                cout << myName.c_str() << "  willRun,number:" <<number << endl;
                caller = myName;
                break;
            }
        }
    }else{
        caller = myName;
    }

    cout << myName.c_str() << "  run,last:" << last <<" number:"<<number<<endl; // 用打印替代执行代码段
    
    if(last){
        caller = std::string(""); // 占用结束把标记量设为初始值
        // mAcquireBufferCond.notify_all();
        mAcquireBufferCond.notify_one();
    }
}

int main()
{
    thread thread1(&func1);
    thread thread2(&func2);
    thread thread3(&func3);

    thread1.join();
    thread2.join();
    thread3.join();
    return 0;
}

void func1()
{
    int i = 0;
    while(1)
    {
        ++i;
        run(std::string("func1"),((i%5) == 0),i); // (i%5)==0   用该语句为真表示整个线程中的一个小阶段
        sleep(1);  // 等待是为了更好的观察运行结果
    }
}

void func2()
{
    int i = 0;
    while(1)
    {
        ++i;
        run(std::string("func2"),((i%5) == 0),i);
        sleep(1);
    }
}

void func3()
{
    int i = 0;
    while(1)
    {
        ++i;
        run(std::string("func3"),((i%5) == 0),i);
        sleep(1);
    }
}

linux上编译命令:   g++   -o   a.out    threadTest.cpp     -lpthread    -std=c++11

执行结果:

############ notify_all() 场景

func1 run,last:0 number:1

func2 wait,number:1

func3 wait,number:1

func1 run,last:0 number:2

func1 run,last:0 number:3

func1 run,last:0 number:4

func1 run,last:1 number:5

func2 willRun,number:1

func2 run,last:0 number:1

func3 wait,number:1

func2 run,last:0 number:2

func1 wait,number:6

func2 run,last:0 number:3

func2 run,last:0 number:4

func2 run,last:1 number:5

func3 willRun,number:1

func3 run,last:0 number:1

func1 wait,number:6

func3 run,last:0 number:2

func2 wait,number:6

func3 run,last:0 number:3

func3 run,last:0 number:4

func3 run,last:1 number:5

func1 willRun,number:6

func1 run,last:0 number:6

func2 wait,number:6

func3 wait,number:6

func1 run,last:0 number:7

func1 run,last:0 number:8

func1 run,last:0 number:9

func1 run,last:1 number:10

func2 willRun,number:6

func2 run,last:0 number:6

func3 wait,number:6

func1 wait,number:11

func2 run,last:0 number:7

func2 run,last:0 number:8

func2 run,last:0 number:9

func2 run,last:1 number:10

func3 willRun,number:6

func3 run,last:0 number:6

func1 wait,number:11

func3 run,last:0 number:7

func2 wait,number:11

func3 run,last:0 number:8

func3 run,last:0 number:9

func3 run,last:1 number:10

func1 willRun,number:11

func1 run,last:0 number:11

func2 wait,number:11

func3 wait,number:11

func1 run,last:0 number:12

func1 run,last:0 number:13

func1 run,last:0 number:14

func1 run,last:1 number:15

func2 willRun,number:11

func2 run,last:0 number:11

func3 wait,number:11

func1 wait,number:16

func2 run,last:0 number:12

func2 run,last:0 number:13

func2 run,last:0 number:14

func2 run,last:1 number:15

func3 willRun,number:11

func3 run,last:0 number:11

func1 wait,number:16


 

##################  notify_one() 情景

func1 run,last:0 number:1

func2 wait,number:1

func3 wait,number:1

func1 run,last:0 number:2

func1 run,last:0 number:3

func1 run,last:0 number:4

func1 run,last:1 number:5

func2 willRun,number:1

func2 run,last:0 number:1

func1 wait,number:6

func2 run,last:0 number:2

func2 run,last:0 number:3

func2 run,last:0 number:4

func2 run,last:1 number:5

func3 willRun,number:1

func3 run,last:0 number:1

func2 wait,number:6

func3 run,last:0 number:2

func3 run,last:0 number:3

func3 run,last:0 number:4

func3 run,last:1 number:5

func1 willRun,number:6

func1 run,last:0 number:6

func1 run,last:0 number:7

func3 wait,number:6

func1 run,last:0 number:8

func1 run,last:0 number:9

func1 run,last:1 number:10

func2 willRun,number:6

func2 run,last:0 number:6

func1 wait,number:11

func2 run,last:0 number:7

func2 run,last:0 number:8

func2 run,last:0 number:9

func2 run,last:1 number:10

func3 willRun,number:6

func3 run,last:0 number:6

func2 wait,number:11

func3 run,last:0 number:7

func3 run,last:0 number:8

func3 run,last:0 number:9

func3 run,last:1 number:10

func1 willRun,number:11

func1 run,last:0 number:11

func3 wait,number:11

func1 run,last:0 number:12

func1 run,last:0 number:13

func1 run,last:0 number:14

func1 run,last:1 number:15

func2 willRun,number:11

func2 run,last:0 number:11

func1 wait,number:16

func2 run,last:0 number:12

func2 run,last:0 number:13

func2 run,last:0 number:14

func2 run,last:1 number:15

func3 willRun,number:11

func3 run,last:0 number:11

func2 wait,number:16

func3 run,last:0 number:12

func3 run,last:0 number:13

func3 run,last:0 number:14

func3 run,last:1 number:15

func1 willRun,number:16

func1 run,last:0 number:16

func3 wait,number:16

func1 run,last:0 number:17

func1 run,last:0 number:18

func1 run,last:0 number:19

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值