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

std::unique_lock在while(1)循环中无法解锁问题求助

问题分析:std::unique_lock 无法获取锁的原因

核心原因:阻塞式IO导致锁长期被持有

你的StdIn_Reader线程中,在持有stdinMutex的状态下调用了read(0, pman->stdin_command, MAXCLIENTMSG)——这是阻塞式读取标准输入的操作。当没有用户输入时,read会一直卡在这行代码上,此时unique_lock始终持有stdinMutex,不会执行后续的lck.unlock()。

而Manager::CommandShell里的std::unique_lock<std::mutex> lck{stdinMutex};是阻塞式获取锁的逻辑,因为锁被StdIn_Reader线程长期占用,这行代码会一直卡住,永远无法执行到cout << "Inside lock\n";,所以只会输出"Entering lock"。

额外的两个逻辑错误

  1. 重复解锁+无效访问:CommandShell里的lck定义在内部{}块中,当块结束时lck会被析构,unique_lock的析构函数会自动调用unlock()。但你在块外又写了lck.unlock();,此时lck已经超出作用域,属于无效内存访问;就算没出作用域,也会导致重复解锁,触发未定义行为。
  2. 共享变量访问遗漏指针:CommandShell里直接访问stdin_command,但它是Manager类的成员,需要通过pman->stdin_command访问,原代码漏了指针,属于编译错误。

修复方案

1. 把阻塞IO移到锁外

只在读写共享变量时加锁,避免锁被阻塞IO占用:

void *StdIn_Reader(void *p)
{
    int nbytes; 
    char temp_buf[MAXCLIENTMSG + 1]; // 用临时缓冲区存读入数据

    while(1)    
    {
        // 先做阻塞读,不持有锁
        nbytes = read(0, temp_buf, MAXCLIENTMSG);
        if (nbytes > 0)
        {
            temp_buf[nbytes]='\0';
            // 仅在修改共享变量时加锁
            std::unique_lock<std::mutex> lck{stdinMutex};
            strcpy(pman->stdin_command, temp_buf);
            lck.unlock(); // 可以提前解锁,或依赖析构自动处理
            pthread_kill(pman->self_id,SIGUSR2);
        }
    }
    return NULL;
}

2. 修正CommandShell的锁逻辑

移除多余的显式解锁,修正共享变量访问方式:

{   
    cout << "Entering lock\n";
    std::unique_lock<std::mutex> lck{stdinMutex};   
    cout << "Inside lock\n";
    if(strlen(pman->stdin_command)){
        strcpy(command+strlen(command), pman->stdin_command);
    }
    pman->stdin_command[0]='\0'; 
    // 无需显式unlock,unique_lock析构时会自动解锁
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:07:27