C语言代码编写需要非常严谨,可能不小就会出现不可避免的错误,这些错误往往是无法进行调试的,特别将这些问题总结下来,提醒自己编写代码细心,严谨!
1、共享资源加锁常见错误:
_scheduleCCBListHeader 链表表头,在代码中可能随时被删除掉。
static int
_scheduleUpdateRemoteUserState(int fd, scheduleIMP *s_imp)
{
char rcv_buf[SCHEDULE_INTERNAL_MSG_MAX_LEN] = { '\0' };
scheduleCCB *s_ccb = _scheduleCCBListHeader;
if (_schedule_sys_id == 0) {
pthread_mutex_lock(&_scheduleCCBListLock);
while (s_ccb) {
if (s_ccb->fd != fd)
_scheduleSyncState(s_ccb->fd, rcv_buf);
s_ccb = s_ccb->next;
}
pthread_mutex_unlock(&_scheduleCCBListLock);
}
return 0;
}
上面的问题在编程中可能会经常遇到,上面代码没有逻辑问题,编译也不会报错,但是在运行中可能会出现预想不到问题,主要还是对共享资源链表 scheduleCCBListHeader使用锁,如果在枷锁前_scheduleCCBListHeader正好被其他程序释放掉或者指向其他地方,那么程序的运行就会出现我们所不能确定的后果,加锁应该在s_ccb = _scheduleCCBListHeader 之前,改写成下面就没有问题了!
static int
_scheduleUpdateRemoteUserState(int fd, scheduleIMP *s_imp)
{
char rcv_buf[SCHEDULE_INTERNAL_MSG_MAX_LEN] = { '\0' };
scheduleCCB *s_ccb = NULL;
if (_schedule_sys_id == 0) {
pthread_mutex_lock(&_scheduleCCBListLock);
s_ccb = _scheduleCCBListHeader;
while (s_ccb) {
if (s_ccb->fd != fd)
_scheduleSyncState(s_ccb->fd, rcv_buf);
s_ccb = s_ccb->next;
}
pthread_mutex_unlock(&_scheduleCCBListLock);
}
return 0;
}
2 线程锁初始化问题
结构体内部锁初始化只能用初始化函数,其他可以直接赋值,如下:
#define SCHEDULE_MAX_MONITOR_USER 256
typedef struct _scheduleVideoMonitor{
char name[ANTA_DEFAULT_SIZE]; /* */
tCCB *ccbs[SCHEDULE_MAX_MONITOR_USER]; /* */
struct _scheduleVideoMonitor *next;
}tScheduleVideoMonitor;
if(pthread_mutex_init(&p_VideoMon->ccbs_lock,NULL) != 0){
free(p_VideoMon);
return NULL;
}
其他情况初始化:
pthread_mutex_t vScheduleVideoMonitorLock = PTHREAD_MUTEX_INITIALIZER;