独特的锁未在 while(1) 内解锁

问题描述 投票:0回答:1

在下一个代码中,尽管已明确解锁,但

std::unique_lock lck
并未在
Manager::CommandShell
中解锁。我能够获得“输入锁”,但不能获得“内部锁”,有人知道为什么解锁不起作用吗?或者也许是这样,但它并不像我想象的那样工作?

std::mutex stdinMutex;
Manager *pman=NULL;

void *StdIn_Reader(void *p)
{
    int nbytes; 

    while(1)    /// Infinite loop
    {
        std::unique_lock<std::mutex> lck{stdinMutex};
        nbytes = read(0,pman->stdin_command,MAXCLIENTMSG);
        if (nbytes > 0)
        {
            pman->stdin_command[nbytes]='\0';
            /// Signal cmd
            pthread_kill(pman->self_id,SIGUSR2);
        }
        lck.unlock();
    }
    return NULL;
}

bool Manager::CommandShell(bool started)
{
    char command[(MAXCLIENTMSG+1)*MAXNUMCOMMANDS];
    // variables to process more than one order in a message (when it happens)

    sigset_t newmask;
    siginfo_t info;
    int rcvd_sig;

    // Mask for block all but SIGUSR1 and SIGUSR2 signals
    sigemptyset(&newmask);
    sigaddset(&newmask, SIGUSR1);
    sigaddset(&newmask, SIGUSR2);

    pthread_sigmask(SIG_BLOCK, &newmask, NULL);

    while (1)
    {
        do{
            rcvd_sig = sigwaitinfo(&newmask, &info);
        }while(rcvd_sig==-1);

        command[0]='\0';

        {   
            cout << "Entering lock\n";
            std::unique_lock<std::mutex> lck{stdinMutex};   
            cout << "Inside lock\n";
            if(strlen(stdin_command)){
                    strcpy(command+strlen(command),stdin_command);
                }
                stdin_command[0]='\0'; 
            }
            lck.unlock();
        }
    }
}
c++ multithreading mutex unique-lock
1个回答
0
投票

一般来说,在执行像

read
这样的阻塞操作时持有互斥锁会导致死锁。

您的代码最简单的解决方案可能是读入临时缓冲区,然后锁定互斥体并复制到您的数据结构中:

    while(1)    /// Infinite loop
    {
        char temp[MAXCLIENTMSG];
        nbytes = read(0,temp,MAXCLIENTMSG);
        if (nbytes > 0)
        {
            std::unique_lock<std::mutex> lck{stdinMutex};
            memcpy(pman->stdin_command, temp, nbytes)
            pman->stdin_command[nbytes]='\0';
            /// Signal cmd
            pthread_kill(pman->self_id,SIGUSR2);
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.