首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

linux下信号量同步多线程有关问题

2012-02-14 
高手请进 linux下信号量同步多线程问题我在编写一个正则表达式匹配多线程库使用信息量来同步工作线程(匹配

高手请进 linux下信号量同步多线程问题
我在编写一个正则表达式匹配多线程库
使用信息量来同步工作线程(匹配线程)并等待处理结果,该程序在测试环境下没有问题,但在我的主程序中出现了问题。
我使用两个信号灯的信号量集,一个用于表示当前可用任务数(为实开工作线程数),一个用于表示当前已经完成的任务数。
程序流量如下:
《主线程》
建立任务数据缓冲区,给所有线程返回
设置已经完成任务信号灯为0,可用任务数信号灯为工作线程数
主线程完成自己的一份,并等待其它工作线程返回
完成任务,并释放缓冲(该处出现读已经FREE的数据)

《工作线程》
等待任务信号量,并取得一个信号资源
工作……
释放任务完成信号量

问题:
该库在测试环境下工作良好,主线程,即为工作(main)主线程。
工作环境,在DLL中,由辅助线程调用,出现段错误问题
使用valgrind检查发现测试环境没有问题,工作环境出现访问free数据。

以下为工作环境调试信息
[DEBUG] 2011-09-24 10:16:08.533 pcre matcher finished work, 244980032 subject:bfd4288, len:172
[DEBUG] 2011-09-24 10:16:08.548 all matcher has finished work.
[DEBUG] 2011-09-24 10:16:08.552 pcre matcher finish release signal...(244980032)
[DEBUG] 2011-09-24 10:16:08.553 pcre matcher wait to work...(244980032)
-----[DEBUG] 2011-09-24 10:16:08.595 pcre matcher finished work, 244980032 subject:bfd4288, len:172
-----[DEBUG] 2011-09-24 10:16:08.596 pcre matcher finish release signal...(244980032)
[DEBUG] 2011-09-24 10:16:08.600 pcre matcher wait to work...(244980032)
红色部分为工作线程多次访问,第二次访问的时候,资源已经释放……就出现问题了

C/C++ code
/** * match a subject using PCRE * return 0 - success, -1 -- failed */int pcre_match(pcre_obj_t* _this, char* subject,    unsigned int subject_len, void** pptag){    int result;    if (_this->threads_count > 1){        pthread_rwlock_rdlock(&_this->rwlock);    }    *pptag = NULL;    /*build subject buff include end 0*/    char* sharesubject;    sharesubject = (char*)malloc(subject_len + 2);    if (sharesubject == NULL) goto clean;    memcpy(sharesubject, subject, subject_len);    sharesubject[subject_len] = '\0';    sharesubject[subject_len+1] = '\0';    /*do match using matcher*/    if (_this->threads_count > 1){        /*enable all thread to work*/        int threadcnt = set_running_thread_match_param(_this->matcher_list,                sharesubject, subject_len, pptag);        threadcnt--; /* reduce main thread's share */        msg_log_debug("let all matcher to work for master, subject address:%x, len%d.", sharesubject, subject_len);        do{            result = semset_set(_this->semid, TASK_FINISH_SEM_IDX, 0);        }while(result == -1 && (errno == EAGAIN || errno == EINTR));        if (result == -1 && !(errno == EAGAIN || errno == EINTR)){            msg_log_warn("Unexpected error on set signal[%d].", errno);        }        do{            result = semset_set(_this->semid, TASK_START_SEMIDX, threadcnt);        }while(result == -1 && (errno == EAGAIN || errno == EINTR));        if (result == -1 && !(errno == EAGAIN || errno == EINTR)){            msg_log_warn("Unexpected error on set signal[%d].", errno);        }        /* do main thread's share */        _this->matcher_list->match_result = pcre_match_item(                _this->matcher_list->pattern_list,                _this->matcher_list->subject,                _this->matcher_list->subject_len,                _this->matcher_list->pptag);        /* wait all threads to finish their share */        msg_log_debug("wait all work matcher threads finish single...");        do{            semset_wait(_this->semid, TASK_FINISH_SEM_IDX, 1, threadcnt);        }while(result == -1 && (errno == EAGAIN || errno == EINTR));        if (result == -1 && !(errno == EAGAIN || errno == EINTR)){            msg_log_warn("Unexpected error on set signal[%d].", errno);        }        msg_log_debug("all matcher has finished work.");        result = get_match_result(_this->matcher_list, pptag);    }else{        result = pcre_match_item(_this->matcher_list->pattern_list,                sharesubject, subject_len, pptag);    }clean:    if (_this->threads_count > 1){        pthread_rwlock_unlock(&_this->rwlock);    }    if (sharesubject != NULL) free(sharesubject);    return result;} 



请求各位给个思路,项目很紧,先行谢过!

[解决办法]
帮顶个
[解决办法]
仅供参考
C/C++ code
#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef WIN32    #include <windows.h>    #include <io.h>#else    #include <unistd.h>    #include <sys/time.h>    #include <pthread.h>    #define  CRITICAL_SECTION   pthread_mutex_t    #define  _vsnprintf         vsnprintf#endif//Log{#define MAXLOGSIZE 100000000#define ARRSIZE(x) (sizeof(x)/sizeof(x[0]))#include <time.h>#include <stdarg.h>char logfilename1[]="MyLog1.log";char logfilename2[]="MyLog2.log";char logstr[16000];char datestr[16];char timestr[16];char ms10[3];CRITICAL_SECTION cs_log;FILE *flog;int centisec() {#ifdef WIN32    return ((GetTickCount()%1000L)/10)%100;#else    struct timeval tv;    if (!gettimeofday(&tv,NULL)) {        return ((tv.tv_usec%1000000L)/10000)%100;    } else {        return 0;    }#endif}#ifdef WIN32void Lock(CRITICAL_SECTION *l) {    EnterCriticalSection(l);}void Unlock(CRITICAL_SECTION *l) {    LeaveCriticalSection(l);}#elsevoid Lock(CRITICAL_SECTION *l) {    pthread_mutex_lock(l);}void Unlock(CRITICAL_SECTION *l) {    pthread_mutex_unlock(l);}#endifvoid LogV(const char *pszFmt,va_list argp) {    struct tm *now;    time_t aclock;    if (NULL==pszFmt||0==pszFmt[0]) return;    if (-1==_vsnprintf(logstr,ARRSIZE(logstr),pszFmt,argp)) logstr[ARRSIZE(logstr)-1]=0;    time(&aclock);    now=localtime(&aclock);    sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);    sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );    sprintf(ms10,"%02d",centisec());    printf("%s %s.%s %s",datestr,timestr,ms10,logstr);    flog=fopen(logfilename1,"a");    if (NULL!=flog) {        fprintf(flog,"%s %s.%s %s",datestr,timestr,ms10,logstr);        if (ftell(flog)>MAXLOGSIZE) {            fclose(flog);            if (rename(logfilename1,logfilename2)) {                remove(logfilename2);                rename(logfilename1,logfilename2);            }            flog=fopen(logfilename1,"a");            if (NULL==flog) return;        }        fclose(flog);    }}void Log(const char *pszFmt,...) {    va_list argp;    Lock(&cs_log);    va_start(argp,pszFmt);    LogV(pszFmt,argp);    va_end(argp);    Unlock(&cs_log);}//Log}int main(int argc,char * argv[]) {    int i;#ifdef WIN32    InitializeCriticalSection(&cs_log);#else    pthread_mutex_init(&cs_log,NULL);#endif    for (i=0;i<10000;i++) {        Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);    }#ifdef WIN32    DeleteCriticalSection(&cs_log);#else    pthread_mutex_destroy(&cs_log);#endif    return 0;} 

热点排行