首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程问题。调试seg-fault

线程问题。调试seg-fault
EN

Stack Overflow用户
提问于 2015-10-20 10:36:11
回答 2查看 30关注 0票数 0

这是一个家庭工作的问题。下面的代码在单线程上运行得很好,但是当多个线程运行时,我会得到seg-faults。我一直在尝试使用valgrind和gdb进行调试,但我搞不清楚。

您是否在此线程中看到会导致问题的任何内容?

代码语言:javascript
复制
static int parse_line(char *line, const char *delim, char *field[])
{
   char *next;
   int cnt = 0;

   next = strtok(line, delim);
   while (next) {
    if (cnt == MAX_NUM_FIELDS - 1)
    break;
    field[cnt] = (char *) malloc(strlen(next) + 1);
    strcpy(field[cnt++], next);
    next = strtok(NULL, delim);
    }
    field[cnt] = (char *) 0;    /* make the field array be    null-terminated */
    int i;
    for (i = 0; i < cnt; i++) {
    free(field[cnt]);
    }
    return cnt;
}

void *process_file(void *ptr)
{
    char *filename = (char *) ptr;
    char *linebuffer = (char *) malloc(sizeof(char) * MAX_LINE_SIZE);
    char **field = (char **) malloc(sizeof(char *) * MAX_NUM_FIELDS);
    char *end_date = (char *) malloc(sizeof(char) * MAX_LINE_SIZE);

    fprintf(stderr, "%s: processing log file %s\n", program_name,
        filename);
    FILE *fin = fopen(filename, "r");
    if (fin == NULL) {
    fprintf(stderr, "Cannot open file %s\n", filename);
    pthread_exit(1);
    }
    char *s = fgets(linebuffer, MAX_LINE_SIZE, fin);
    if (s != NULL) {
    int num = parse_line(linebuffer, " []\"", field);
    update_webstats(num, field);
    printf("Starting date: %s\n", field[3]);
    free_tokens(num, field);

    while (fgets(linebuffer, MAX_LINE_SIZE, fin) != NULL) {
        int num = parse_line(linebuffer, " []\"", field);
        strcpy(end_date, field[3]);
        update_webstats(num, field);
        free_tokens(num, field);
        strcpy(linebuffer, "");
    }
    printf("Ending date: %s\n", end_date);

    }
    free(end_date);
    free(field);
    free(linebuffer);
    fclose(fin);
    pthread_exit(NULL);
}
EN

回答 2

Stack Overflow用户

发布于 2015-10-21 06:12:36

您的问题是strtok()不能从多个线程同时使用,因为它使用静态内部状态(它不是可重入的)。

POSIX包含一个可重入的strtok()变体,名为strtok_r() -您应该改用以下代码:

代码语言:javascript
复制
static int parse_line(char *line, const char *delim, char *field[])
 {
   char *next;
   int cnt = 0;
   char *saveptr;

   next = strtok_r(line, delim, &saveptr);
   while (next) {
       if (cnt == MAX_NUM_FIELDS - 1)
            break;
       field[cnt] = (char *) malloc(strlen(next) + 1);
       strcpy(field[cnt++], next);
       next = strtok_r(NULL, delim, &saveptr);
   }
   field[cnt] = (char *) 0; /* make the field array be    null-terminated */
   int i;
   for (i = 0; i < cnt; i++) {
       free(field[cnt]);
   }
   return cnt;
}
票数 1
EN

Stack Overflow用户

发布于 2015-10-20 23:31:56

我找到问题了。这段代码调用strtok,它不是线程安全的。应为strtokk_r

代码语言:javascript
复制
static int parse_line(char *line, const char *delim, char *field[])
 {
   char *next;
   int cnt = 0;

   next = strtok(line, delim);
   while (next) {
    if (cnt == MAX_NUM_FIELDS - 1)
    break;
    field[cnt] = (char *) malloc(strlen(next) + 1);
    strcpy(field[cnt++], next);
    next = strtok(NULL, delim);
    }
    field[cnt] = (char *) 0;    /* make the field array be    null-terminated */
    int i;
    for (i = 0; i < cnt; i++) {
    free(field[cnt]);
    }
    return cnt;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33227049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档