在下一个代码中,尽管已明确解锁,但
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();
}
}
}
一般来说,在执行像
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);
}
}