我的程序在 Windows(Windows 7 - 32 位)中因访问冲突而死。是MinGW下用gcc 4.8.1编译的C代码。它使用 pthreads-w32 2.9.1。有几个线程同时工作,没有其他明显问题。它可以运行好几天,也可以在几个小时内失败。代码也可以在几种 linux 架构中编译,但我在那里没有问题。在调试器下运行程序也非常困难。
以下是发生崩溃的函数。
static void *timeout_lector(void *indice)
{
int e;
pthread_mutex_t fm;
pthread_cond_t fc;
struct timespec ts;
struct timeval tv;
struct equipo *eq;
eq = &estacion.equipos[*((int *)indice)];
if (pthread_mutex_init(&fm, NULL) || pthread_cond_init(&fc, NULL)) {
LOG_PRINT("Error creating mutex or cond in timeout_lector.\n");
exit(1);
}
pthread_mutex_lock(&fm);
gettimeofday(&tv, NULL);
ts.tv_sec = tv.tv_sec;
ts.tv_nsec = tv.tv_usec * 1000;
siguiente_tmseg(&ts, 150); /* Increments ts by 150 ms */
pthread_cleanup_push(thread_cleanup_fc, (void *)(&fc));
pthread_cleanup_push(thread_cleanup_fm, (void *)(&fm));
if ((e = pthread_cond_timedwait(&fc, &fm, &ts)) != ETIMEDOUT) {
LOG_PRINT("Error waiting in timeout_lector: %d.\n", e);
exit(1);
}
pthread_mutex_lock(&eq->mutexto);
eq->to = 1;
pthread_mutex_unlock(&eq->mutexto);
e = pthread_cond_wait(&fc, &fm); /* wait until we are cancelled */
LOG_PRINT("Error in timeout_lector: %d.\n", e);
exit(1);
/* Next lines are never executed and just for correct syntax */
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
return(NULL);
}
这些是清理功能:
void thread_cleanup_fc(void *fc)
{
pthread_cond_destroy(fc);
}
void thread_cleanup_fm(void *fm)
{
pthread_mutex_unlock(fm);
pthread_mutex_destroy(fm);
}
我一直在使用 Dr.MinGW 0.7.3 运行它,这是报告:
estacion.exe caused an Access Violation at location 62489D38 in module pthreadGC2.dll Writing to location 0101FCFC.
Registers:
eax=00000000 ebx=0444febc ecx=ffffffff edx=0101fcfc esi=0444fee0 edi=0444fcf0
eip=62489d38 esp=0444fcd0 ebp=0444fd18 iopl=0 nv up ei pl zr na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
AddrPC Params
62489D38 0444FEE0 00000000 FFFFFFFF pthreadGC2.dll!pthread_cond_destroy
004194E0 0444FEE0 0444FEBC 0444FD68 estacion.exe!thread_cleanup_fc [C:/codigo/CeltaDAS/estacion/tiempo.c @ 223]
6248ABB5 00000684 FFFFFFFF 0444FE08 pthreadGC2.dll!ptw32_pop_cleanup.constprop.3
6248BAAF 00000000 00000000 03C63EE0 pthreadGC2.dll!sem_timedwait
6248512D 003E1138 0444FEB0 767DA53A pthreadGC2.dll!pthread_getspecific
62485D22 003E1138 00000078 00000000 pthreadGC2.dll!ptw32_push_cleanup
62485D22 0444FEE0 0444FEE4 0444FED0 pthreadGC2.dll!ptw32_push_cleanup
0040C0D1 014908EC 014AAD70 00000000 estacion.exe!timeout_lector [C:/codigo/CeltaDAS/estacion/equipos.c @ 214]
62485BD3 014B1190 0805AA4A 00000000 pthreadGC2.dll!ptw32_threadStart@4
767E1287 0444FF94 773DEE1C 03CF0048 msvcrt.dll!itow_s
767E1328 03CF0048 0444FFD4 777037EB msvcrt.dll!endthreadex
773DEE1C 03CF0048 319EB544 00000000 kernel32.dll!BaseThreadInitThunk
777037EB 767E12E5 03CF0048 00000000 ntdll.dll!RtlInitializeExceptionChain
777037BE 767E12E5 03CF0048 00000000 ntdll.dll!RtlInitializeExceptionChain
Windows 6.1.7601
DrMingw 0.7.3
Dr.MinGW 在通过 timeout_lector 中的第 214 行的堆栈跟踪中报告。它对应于代码中的 pthread_cond_wait 行。
该线程是连续创建的,并且是多个并行创建的。他们等待一段时间,而他们可以被取消,如果时间过去了,他们会改变一个变量,然后等到他们被取消,这几乎立即由另一个线程发生。没有太多可取消的函数可以用于等待,并且可以在不同的系统中移植,所以我选择了 pthread_cond_timedwait 。但问题似乎在于第二次无限期的等待。
我搜索了类似的问题,但似乎没有什么是相同的问题。更相似的是:
pthread_cond_wait:随机分段错误
取消 pthread_cond_wait() 挂起与 PRIO_INHERIT 互斥锁
如果有人可以帮助我,我将不胜感激。