1

我的程序在 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 互斥锁

如果有人可以帮助我,我将不胜感激。

4

1 回答 1

0

First destroy mutex and condition on which thread is waiting and then do thread cancel. If you destroy first thread then this kind of problem comes in windows. Have look on this.

于 2015-08-20T10:48:27.160 回答