我正在为Linux OS编写C程序。
该程序可以启动一个计时器:主程序和计时器都可以在串行端口上发送和接收字符。
我的尝试是通过在开头用
if (pthread_mutex_init( &pED->lockSerial, NULL) != 0)
{
lwsl_err("lockSerial init failed\n");
}
我保护了在端口上发送数据的所有功能,如下所示:
ssize_t cmdFirmwareVersion(EngineData *pED)
{
if (pED->fdSerialPort==-1)
return -1;
LOCK_SERIAL;
unsigned char cmd[] = { 0x00, 0x00, 0x7F };
write( pED->fdSerialPort, cmd, sizeof(cmd));
int rx = read ( pED->fdSerialPort, rxbuffer, sizeof rxbuffer);
dump( rxbuffer, rx);
UNLOCK_SERIAL;
return rx;
}
其中
#define LOCK_SERIAL if (0!=pthread_mutex_lock(&pED->lockSerial)) {printf("Err lock");return 0;}
#define UNLOCK_SERIAL pthread_mutex_unlock(&pED->lockSerial);
运行程序并启动计时器,我看到请求是正常的。当我以其他方式(从rx websocket函数)触发此调用之一时,程序挂起,我需要将其杀死。
为什么整个程序都停止了?
答案 0 :(得分:1)
如果进程挂起,则可能是因为循环等待互斥锁或保持互斥锁并尝试再次锁定它。这可能会导致死锁。
如果正在等待资源,则ps输出将线程状态显示为D或S。它会在进程挂起时显示。
D uninterruptible sleep (usually IO)
S interruptible sleep (waiting for an event to complete)
我创建了一个线程来保存互斥锁,然后尝试再次锁定它。 ps输出,GDB显示主线程和子线程处于睡眠状态。
xxxx@virtualBox:~$ ps -eflT |grep a.out
0 S root 3982 3982 2265 0 80 0 - 22155 - 20:28 pts/0 00:00:00 ./a.out
1 S root 3982 3984 2265 0 80 0 - 22155 - 20:28 pts/0 00:00:00 ./a.out
(gdb) info threads
Id Target Id Frame
* 1 Thread 0x7ffff7fdf740 (LWP 4625) "a.out" 0x00007ffff7bbed2d in __GI___pthread_timedjoin_ex (
threadid=140737345505024, thread_return=0x0, abstime=0x0, block= <optimized out>) at pthread_join_common.c:89
2 Thread 0x7ffff77c4700 (LWP 4629) "a.out" __lll_lock_wait ()
at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
请查看博客Tech Easy,以获取有关线程的更多信息。