You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程调用不同函数时如何仅锁定全局变量而非整个函数

如何仅锁定全局变量而非整个函数实现线程并发自增

我通过两个线程调用两个独立函数对全局变量进行自增操作,使用了std::lock_guard。但输出结果显示func1执行完成后func2才开始,呈现单线程运行的效果。请问如何仅锁定全局变量而非整个函数?

原代码

#include <iostream>
#include <thread>
#include <mutex>

using namespace std;

// 全局变量
int number;

std::mutex myMutex;

void func1(int interval)
{
    std::lock_guard<std::mutex> lock (myMutex);
    for(int i = 0; i< interval; i++)
    {
        cout<<"thread one " << ++number<<std::endl;
    }
}

void func2(int interval)
{
    std::lock_guard<std::mutex> lock (myMutex);
    for(int i = 0; i< interval; i++)
    {
        cout<<"thread two " << ++number<<std::endl;
    }
}

int main()
{
    std::thread t1(func1, 1000);
    std::thread t2(func2, 1000);

    t1.join();
    t2.join();

    return 0;
}

问题原因

你当前的代码把std::lock_guard放在了for循环外部,这意味着整个func1/func2函数执行期间都会持有互斥锁。当其中一个线程先获取锁后,另一个线程只能等待锁被释放才能开始运行,最终就表现为单线程串行执行的效果。

解决方法

将std::lock_guard移到for循环内部,让锁仅在操作共享资源(全局变量number和标准输出cout)的代码块生效,这样每次循环只会短暂持有锁,执行完自增和输出后立刻释放,两个线程就能交替获取锁并发执行:

修改后的代码:

#include <iostream>
#include <thread>
#include <mutex>

using namespace std;

// 全局变量
int number;

std::mutex myMutex;

void func1(int interval)
{
    for(int i = 0; i< interval; i++)
    {
        std::lock_guard<std::mutex> lock (myMutex);
        cout<<"thread one " << ++number<<std::endl;
    }
}

void func2(int interval)
{
    for(int i = 0; i< interval; i++)
    {
        std::lock_guard<std::mutex> lock (myMutex);
        cout<<"thread two " << ++number<<std::endl;
    }
}

int main()
{
    std::thread t1(func1, 1000);
    std::thread t2(func2, 1000);

    t1.join();
    t2.join();

    return 0;
}

补充说明

  • std::cout是全局共享资源,不加锁的话多个线程同时输出会导致打印内容错乱,所以必须把输出操作也包含在锁的保护范围内。
  • std::lock_guard会在作用域结束时自动释放锁,放在循环内部的话,每次循环结束都会自动解锁,无需手动操作,保证了锁的正确释放。

内容的提问来源于stack exchange,提问作者gopinath bb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 01:20:30