2017-01-04 13 views
1

ダブルリンクリストを2つの部分で実装しようとしています。 最初はリストを作成するための関数です。 2番目のシミュレータは、いくつかのスレッド、リーダとライタ(whileループではダブルリンクリストにポップしてプッシュする)と、リストが大きすぎるとリストを消去する(argvに従って) 。 リストはmutexと条件付き変数を使用してスレッドセーフにします。 しかし、私が実行するたびに、私はダブルフリー/メモリ破損(ファストトップ)エラーが発生し、なぜ私は知らない。私はいくつかの助けに感謝します。ダブルリンクリスト - メモリ破損

#include <pthread.h> 
#include <time.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <errno.h> 

#define USAGE_ERR "Usage: ./hw3 <WNUM> <RNUM> <MAX> <TIME>\n" 

/* Argc parameter indexing consts */ 
#define INPUT_WNUM_IDX 1 
#define INPUT_RNUM_IDX 2 
#define OUTPUT_MAX_IDX 3 
#define OUTPUT_TIME_IDX 4 

typedef struct node { 
    int value; 

    struct node * previous; 
    struct node * next; 
} 
node; 

typedef struct { 
    int length; 
    node * head; 
    node * tail; 
    pthread_mutex_t mutex; 
} 
list; 

list * global_list; 
int stop_threads = 0; 
int MAX_LIST_SIZE; 
pthread_cond_t  gc_cond = PTHREAD_COND_INITIALIZER; 
pthread_mutex_t  gc_mutex = PTHREAD_MUTEX_INITIALIZER; 

pthread_cond_t  read_cond = PTHREAD_COND_INITIALIZER; 
pthread_mutex_t  read_mutex = PTHREAD_MUTEX_INITIALIZER; 

list * initlist_create(); 
void initlist_destroy(list * target_list); 
list * initlist_push_head(list * target_list, int value); 
int initlist_pop_tail(list * target_list); 
void initlist_remove_last_k(list * target_list, int k); 
int initlist_size(list * target_list); 
pthread_mutex_t initlist_get_mutex(list * target_list); 
void writer_thread(); 
void reader_thread(); 
void garbage_collect_thread(); 


list * initlist_create() { 
    size_t list_size = sizeof(list); 
    list * new_list = (list *) malloc(list_size); 
    new_list->head = NULL; 
    new_list->tail = NULL; 
    new_list->length = 0; 
    if (0 != pthread_mutex_init(& (new_list->mutex), NULL)) { 
     exit(errno); 
    } 
    return new_list; 
} 

void initlist_destroy(list * target_list) { 
    node * current_node; 
    node * temp_node; 

    if (0 != pthread_mutex_lock(& (target_list->mutex))) { 
     exit(errno); 
    } 

    if (0 != target_list->length) { 
     current_node = target_list->head; 
     while (current_node != NULL) { 
      temp_node = current_node->next; 
      free(current_node); 
      current_node = temp_node; 
     } 
    } 

    if (0 != pthread_mutex_unlock(& (target_list->mutex))) { 
     exit(errno); 
    } 

    if (0 != pthread_mutex_destroy(& (target_list->mutex))) { 
     exit(errno); 
    } 

    free(target_list); 
} 

list * initlist_push_head(list * target_list, int value) { 
    node * new_node; 
    size_t node_size = sizeof(node); 


    if (0 != pthread_mutex_lock(& (target_list->mutex))) { 
     exit(errno); 
    } 

    new_node = (node *) malloc(node_size); 
    if(NULL == new_node) 
    { 
     printf("Malloc failed\n"); 
     exit(errno); 
    } 
    new_node->value = value; 


    if (NULL != target_list->head) { 
     new_node->next = target_list->head; 
     new_node->previous = target_list->tail; 
     target_list->head->previous = new_node; 
     target_list->tail->previous = new_node; 
    } 
    else{ 
     target_list->tail = new_node; 
    } 

    target_list->head = new_node; 
    target_list->length++; 
    if(0 < target_list->length){ 
     pthread_cond_signal(&read_cond); 
    } 
    if (0 != pthread_mutex_unlock(& (target_list->mutex))) { 
     exit(errno); 
    } 
    return target_list; 
} 

int initlist_pop_tail(list * target_list) { 
    int deleted_node_value; 

    if (0 != pthread_mutex_lock(& (target_list->mutex))) { 
     exit(errno); 
    } 
    while(0 == target_list->length){ 
     pthread_cond_wait(&read_cond, &target_list->mutex); 
    } 
    node * last_node = target_list->tail; 


    if (1 == target_list->length) { 
     last_node = target_list->head; 
     target_list->head = NULL; 
     target_list->tail = NULL; 
    } else { 
     target_list->tail = last_node->previous; 
     target_list->tail->next = target_list->head; 
    } 
    deleted_node_value = last_node->value; 


    // IMPORTANT 
    // If i uncomment this, segfault and memory corruption,no idea why 
    //free(last_node); 

    target_list->length--; 
    if (0 != pthread_mutex_unlock(& (target_list->mutex))) { 
     exit(errno); 
    } 
    // if (0 != pthread_mutex_unlock(& (read_mutex))) { 
    // exit(errno); 
    // } 

    return deleted_node_value; 
} 

void initlist_remove_last_k(list * target_list, int k) { 
    int remove_size = k; 
    if (0 != pthread_mutex_lock(& (target_list->mutex))) { 
     exit(errno); 
    } 
    if (k > target_list->length) 
    { 
     remove_size = target_list->length; 
    } 
    if (0 != pthread_mutex_unlock(& (target_list->mutex))) { 
     exit(errno); 
    } 
    for (int i = 0; i < remove_size; ++i) { 
     initlist_pop_tail(target_list); 
    } 
} 

int initlist_size(list * target_list) { 
    int list_size; 

    if (0 != pthread_mutex_lock(& (target_list->mutex))) { 
     exit(errno); 
    } 

    list_size = target_list->length; 

    if (0 != pthread_mutex_unlock(& (target_list->mutex))) { 
     exit(errno); 
    } 

    return list_size; 
} 

pthread_mutex_t initlist_get_mutex(list * target_list) { 
    pthread_mutex_t list_mutex; 

    if (0 != pthread_mutex_lock(& (target_list->mutex))) { 
     exit(errno); 
    } 

    list_mutex = target_list->mutex; 

    if (0 != pthread_mutex_unlock(& (target_list->mutex))) { 
     exit(errno); 
    } 

    return list_mutex; 

} 

void writer_thread() 
{ 
    while (1) 
    { 
     if(stop_threads){ 
      return; 
     } 
     if (MAX_LIST_SIZE < initlist_size(global_list)) 
     { 
      pthread_cond_signal(&gc_cond); 
     } 
     initlist_push_head(global_list, rand()); 

    } 
} 


void reader_thread() 
{ 
    while (1) 
    { 
     if(stop_threads){ 
      return; 
     } 
     if (MAX_LIST_SIZE < initlist_size(global_list)) 
     { 
      pthread_cond_signal(&gc_cond); 
     } 
     initlist_pop_tail(global_list); 

    } 
} 

void garbage_collect_thread() 
{ 
    while(1){ 
     if(stop_threads){ 
      return; 
     } 
     pthread_cond_wait(&gc_cond, &gc_mutex); 
     int remove_count = (initlist_size(global_list)/2); 
     initlist_remove_last_k(global_list, remove_count); 
     printf("GC – %d items removed from the list\r\n", remove_count); 
     if (0 != pthread_mutex_unlock(& (gc_mutex))) { 
      exit(errno); 
     } 
    } 
} 




int main(int argc, char * * argv) { 
    /* Validate arguments */ 
    if (5 != argc) { 
     printf(USAGE_ERR); 
     exit(errno); 
    } 

    int writers_count  = atoi(argv[INPUT_WNUM_IDX]); 
    int readers_count  = atoi(argv[INPUT_RNUM_IDX]); 
    int max_run_time   = atoi(argv[OUTPUT_TIME_IDX]); 
    MAX_LIST_SIZE   = atoi(argv[OUTPUT_MAX_IDX]); 
    global_list = initlist_create(); 


    pthread_t garbage_collector_thread; 

    pthread_t writer_threads[writers_count]; 
    pthread_t reader_threads[readers_count]; 

    if (0 != pthread_create(&garbage_collector_thread, NULL, garbage_collect_thread, NULL)) 

     {  exit(errno); 
     } 

     for (int i = 0; i < writers_count; ++i) 
     { 
      if (0 != pthread_create(&writer_threads[i], NULL, writer_thread, NULL)) 
      { 
       exit(errno); 
      } 
     } 


     for (int x = 0; x < readers_count; ++x) 
     { 
      if (0 != pthread_create(&reader_threads[x], NULL, reader_thread, NULL)) 
      { 
       exit(errno); 
      } 
     } 

     sleep(max_run_time); 
     //IMPORTANT 
     //threads should die after this is set,but all threads wait for the mutex to free 
     //in gcc - see "info threads" command in gdb 

     stop_threads = 1; 
     int list_size = initlist_size(global_list); 
     printf("List size: %d", list_size); 

     for (int i = 0; i < list_size; ++i) 
     { 
      continue; 
      printf("num is %d", initlist_pop_tail(global_list)); 
     } 

     //this gets stuck also when waiting for mutex obviously... 
     initlist_destroy(global_list); 


    } 
+0

注:コメント中の興味深いUnicode文字 '... 1より大きい斑点 '問題の一部ではないと判断して、注意散漫を除去することを提案します。 – chux

+0

が削除されましたが、コンパイル時にコメントがストライプされています... – lippy1234

+0

おそらく 'void reader_thread()' - > 'void * reader_thread(void * x_void_ptr)'です。すべての警告を有効にすることで発見 - デバッグ時間を節約し、試してみてください。 [Ref](http://timmurphy.org/2010/05/04/pthreads-in-ca-minimal-working-example/) – chux

答えて

0
#include <pthread.h> 
#include <time.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <errno.h> 

#define USAGE_ERR "Usage: ./hw3 <WNUM> <RNUM> <MAX> <TIME>\n" 

/* Argc parameter indexing consts */ 
#define INPUT_WNUM_IDX 1 
#define INPUT_RNUM_IDX 2 
#define OUTPUT_MAX_IDX 3 
#define OUTPUT_TIME_IDX 4 

typedef struct node { 
    int value; 

    struct node * previous; 
    struct node * next; 
} 
node; 

typedef struct { 
    int length; 
    node * head; 
    node * tail; 
    pthread_mutex_t mutex; 
} 
list; 

list * global_list; 
int stop_threads = 0; 
int MAX_LIST_SIZE; 
pthread_cond_t  gc_cond = PTHREAD_COND_INITIALIZER; 
pthread_mutex_t  gc_mutex = PTHREAD_MUTEX_INITIALIZER; 

pthread_cond_t  read_cond = PTHREAD_COND_INITIALIZER; 
pthread_mutex_t  read_mutex = PTHREAD_MUTEX_INITIALIZER; 

list * initlist_create(); 
void initlist_destroy(list * target_list); 
list * initlist_push_head(list * target_list, int value); 
int initlist_pop_tail(list * target_list); 
void initlist_remove_last_k(list * target_list, int k); 
int initlist_size(list * target_list); 
pthread_mutex_t initlist_get_mutex(list * target_list); 
void writer_thread(); 
void reader_thread(); 
void garbage_collect_thread(); 


list * initlist_create() { 
    size_t list_size = sizeof(list); 
    list * new_list = (list *) malloc(list_size); 
    new_list->head = NULL; 
    new_list->tail = NULL; 
    new_list->length = 0; 
    if (0 != pthread_mutex_init(& (new_list->mutex), NULL)) { 
     exit(errno); 
    } 
    return new_list; 
} 

void initlist_destroy(list * target_list) { 
    node * current_node; 
    node * temp_node; 

    if (0 != pthread_mutex_lock(& (target_list->mutex))) { 
     exit(errno); 
    } 

    if (0 != target_list->length) { 
     current_node = target_list->head; 
     while (current_node != NULL) { 
      temp_node = current_node->next; 
      free(current_node); 
      current_node = temp_node; 
     } 
    } 

    if (0 != pthread_mutex_unlock(& (target_list->mutex))) { 
     exit(errno); 
    } 

    if (0 != pthread_mutex_destroy(& (target_list->mutex))) { 
     exit(errno); 
    } 

    free(target_list); 
} 

list * initlist_push_head(list * target_list, int value) { 
    node * new_node; 
    size_t node_size = sizeof(node); 


    if (0 != pthread_mutex_lock(& (target_list->mutex))) { 
     exit(errno); 
    } 

    new_node = (node *) malloc(node_size); 
    if (NULL == new_node) 
    { 
     printf("Malloc failed\n"); 
     exit(errno); 
    } 
    new_node->value = value; 

    if (0 == target_list->length) { 
     target_list->tail = new_node; 
    } 
    else { 
     target_list->head->previous = new_node; 
    } 
    new_node->next = target_list->head; 
    target_list->head = new_node; 

    pthread_cond_signal(&read_cond); 
    target_list->length++; 
    if (0 != pthread_mutex_unlock(& (target_list->mutex))) { 
     exit(errno); 
    } 
    return target_list; 
} 

int initlist_pop_tail(list * target_list) { 
    int deleted_node_value; 

    if (0 != pthread_mutex_lock(& (target_list->mutex))) { 
     exit(errno); 
    } 
    while(0 == target_list->length) { 
     pthread_cond_wait(&read_cond, &target_list->mutex); 
    } 
    node * last_node = target_list->tail; 
    deleted_node_value = last_node->value; 
    target_list->tail = last_node->previous; 
    if (last_node->previous != NULL) { 
     last_node->previous->next = NULL; 
     } 
    else 
    { 
     target_list->head = NULL; 

    } 
    target_list->length--; 
    if (0 != pthread_mutex_unlock(& (target_list->mutex))) { 
     exit(errno); 
    } 
    last_node->next = NULL; 
    last_node->previous = NULL; 
    free(last_node); 



    // node *result = NULL; 
    // lock(&list_ptr->mutex); 
    // if (list_ptr->head != NULL) { 
    //  result = list_ptr->tail; 
    //  list_ptr->tail = result->prev; 
    //  if (result->prev != NULL) { 
    //   result->prev->next = NULL; 
    //  } 
    //  else { 
    //   list_ptr->head = NULL; 
    //  } 
    //  list_ptr->length--; 
    // } 
    // unlock(&list_ptr->mutex); 
    // if (result != NULL) { 
    //  result->next = NULL; 
    //  result->prev = NULL; 
    // } 
    // return result; 

    return deleted_node_value; 
} 

void initlist_remove_last_k(list * target_list, int k) { 
    int remove_size = k; 
    if (0 != pthread_mutex_lock(& (target_list->mutex))) { 
     exit(errno); 
    } 
    if (k > target_list->length) 
    { 
     remove_size = target_list->length; 
    } 
    if (0 != pthread_mutex_unlock(& (target_list->mutex))) { 
     exit(errno); 
    } 
    for (int i = 0; i < remove_size; ++i) { 
     initlist_pop_tail(target_list); 
    } 
} 

int initlist_size(list * target_list) { 
    int list_size; 

    if (0 != pthread_mutex_lock(& (target_list->mutex))) { 
     exit(errno); 
    } 

    list_size = target_list->length; 

    if (0 != pthread_mutex_unlock(& (target_list->mutex))) { 
     exit(errno); 
    } 

    return list_size; 
} 

pthread_mutex_t initlist_get_mutex(list * target_list) { 
    pthread_mutex_t list_mutex; 

    list_mutex = target_list->mutex; 

    return list_mutex; 

} 

void writer_thread() 
{ 
    while (1) 
    { 
     if (stop_threads) { 
      return; 
     } 
     if (MAX_LIST_SIZE < initlist_size(global_list)) 
     { 

      pthread_cond_signal(&gc_cond); 
     } 
     initlist_push_head(global_list, rand()); 

    } 
} 


void reader_thread() 
{ 
    while (1) 
    { 
     if (stop_threads) { 
      return; 
     } 
     if (MAX_LIST_SIZE < initlist_size(global_list)) 
     { 
      pthread_cond_signal(&gc_cond); 
     } 
     initlist_pop_tail(global_list); 

    } 
} 

void garbage_collect_thread() 
{ 
    while(1) { 
     if (stop_threads) { 
      return; 
     } 

     if (0 != pthread_mutex_lock(& (gc_mutex))) { 
      exit(errno); 
     } 
     pthread_cond_wait(&gc_cond, &(gc_mutex)); 
     int remove_count = (initlist_size(global_list)/2); 
     if (0 == remove_count){ 
      continue; 
     } 
     initlist_remove_last_k(global_list, remove_count); 
     printf("GC – %d items removed from the list\r\n", remove_count); 
     if (0 != pthread_mutex_unlock(& (gc_mutex))) { 
      exit(errno); 
     } 
    } 
} 

int main(int argc, char * * argv) { 
    /* Validate arguments */ 
    if (5 != argc) { 
     printf(USAGE_ERR); 
     exit(errno); 
    } 

    int writers_count  = atoi(argv[INPUT_WNUM_IDX]); 
    int readers_count  = atoi(argv[INPUT_RNUM_IDX]); 
    int max_run_time   = atoi(argv[OUTPUT_TIME_IDX]); 
    MAX_LIST_SIZE   = atoi(argv[OUTPUT_MAX_IDX]); 
    global_list = initlist_create(); 


    pthread_t garbage_collector_thread; 

    pthread_t writer_threads[writers_count]; 
    pthread_t reader_threads[readers_count]; 

    if (0 != pthread_create(&garbage_collector_thread, NULL, garbage_collect_thread, NULL)) 

    { exit(errno); 
    } 

    for (int i = 0; i < writers_count; ++i) 
    { 
     if (0 != pthread_create(&writer_threads[i], NULL, writer_thread, NULL)) 
     { 
      exit(errno); 
     } 
    } 


    for (int x = 0; x < readers_count; ++x) 
    { 
     if (0 != pthread_create(&reader_threads[x], NULL, reader_thread, NULL)) 
     { 
      exit(errno); 
     } 
    } 


    sleep(max_run_time); 
    stop_threads = 1; 
    int list_size = initlist_size(global_list); 
    printf("List size: %d\r\n", list_size); 

    for (int i = 0; i < readers_count; ++i) 
    { 
     pthread_cancel(&reader_threads[i]); 
    } 
    for (int i = 0; i < writers_count; ++i) 
    { 
     pthread_cancel(&writer_threads[i]); 
    } 

    for (int i = 0; i < list_size; ++i) 
    { 
     printf("num is %d\r\n", initlist_pop_tail(global_list)); 
    } 

    initlist_destroy(global_list); 


} 
0

私は、デバッガでコードを実行し、initlist_destroyから、このコードでは二度同じポインタを解放しようとする試みがあります:

if (0 != target_list->length) { 
    current_node = target_list->head; 
    while (current_node != NULL) { 
     temp_node = current_node->next; 
     // Added the following line to view pointer values 
     printf("Freeing %p...\n", current_node); 
     free(current_node); 
     current_node = temp_node; 
    } 
} 

私は、ポインタ値をプリントアウトし、Iこのような出力を得る:あなたが見ることができるように、あなたは二度同じポインタを解放しよう

GC – 5 items removed from the list 
List size: 4 
Freeing 0x7fc1a1602d20... 
Freeing 0x7fc1a15045e0... 
Freeing 0x7fc1a3569c40... 
Freeing 0x7fc1a3569c40... 

。リスト処理コードに不備があります。これは驚くべきことではありません。リンクされたリストコードは書きにくい。

私の推薦(例えば3)

  • リストから各項目を削除リストにアイテムの小さい番号を追加

    1. がリンクリスト
    2. を作成シングルスレッドプログラムを作成することです
    3. リストは、私が読みやすいでは、リストのポインタを表示する関数を記述します

  • 空で確認(例えば、 16進値の表)。リストを変更するたびにその関数を呼び出します。あなたが間違っていることが分かりやすいはずです。

    更新

    私は上記の提案を実現するプログラムを書いた:

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <errno.h> 
    #include <pthread.h> 
    #include <inttypes.h> 
    
    #define PTR_FMT "0x%016" PRIXPTR 
    
    void perror_location(const char *file, int line_number) { 
        char location[80]; 
        snprintf(location, sizeof(location), "%s:%d", file, line_number); 
        perror(location); 
        exit(errno); 
    } 
    
    #define PERROR() perror_location(__FILE__, __LINE__) 
    
    void *malloc_safe(size_t size) { 
        void *result = malloc(size); 
        if (NULL == result) { 
         PERROR(); 
        } 
        return result; 
    } 
    
    #define MALLOC(type) \ 
        (type *) malloc_safe(sizeof(type)) 
    
    void lock(pthread_mutex_t *mutex) { 
        if (0 != pthread_mutex_lock(mutex)) { 
         PERROR(); 
        } 
    } 
    
    void unlock(pthread_mutex_t *mutex) { 
        if (0 != pthread_mutex_unlock(mutex)) { 
         PERROR(); 
        } 
    } 
    
    typedef struct _node { 
        int value; 
        struct _node *next; 
        struct _node *prev; 
    } node; 
    
    typedef struct _list { 
        node *head; 
        node *tail; 
        size_t length; 
        pthread_mutex_t mutex; 
    } list; 
    
    list *list_init(void) { 
        list *result = MALLOC(list); 
        result->head = NULL; 
        result->tail = NULL; 
        result->length = 0; 
        if (0 != pthread_mutex_init(&result->mutex, NULL)) { 
         PERROR(); 
        } 
        return result; 
    } 
    
    node *list_add(list *list_ptr, int value) { 
        node *result = MALLOC(node); 
        result->value = value; 
        result->next = NULL; 
        result->prev = NULL; 
        lock(&list_ptr->mutex); 
        if (list_ptr->head == NULL) { 
         list_ptr->head = result; 
         list_ptr->tail = result; 
        } 
        else { 
         result->prev = list_ptr->tail; 
         list_ptr->tail->next = result; 
         list_ptr->tail = result; 
        } 
        list_ptr->length++; 
        unlock(&list_ptr->mutex); 
        return result; 
    } 
    
    node *list_remove(list *list_ptr) { 
        node *result = NULL; 
        lock(&list_ptr->mutex); 
        if (list_ptr->head != NULL) { 
         result = list_ptr->tail; 
         list_ptr->tail = result->prev; 
         if (result->prev != NULL) { 
          result->prev->next = NULL; 
         } 
         else { 
          list_ptr->head = NULL; 
         } 
         list_ptr->length--; 
        } 
        unlock(&list_ptr->mutex); 
        if (result != NULL) { 
         result->next = NULL; 
         result->prev = NULL; 
        } 
        return result; 
    } 
    
    void list_print(list *list_ptr) { 
        lock(&list_ptr->mutex); 
        printf("----------\n"); 
        printf("length = %ld\n", list_ptr->length); 
        printf("%-18s %-18s %-18s\n", "list", "list->head", "list->tail"); 
        printf(PTR_FMT " " PTR_FMT " " PTR_FMT "\n", 
          (uintptr_t) list_ptr, 
          (uintptr_t) list_ptr->head, 
          (uintptr_t) list_ptr->tail); 
        if (list_ptr->head != NULL) { 
         printf("%-18s %-18s %-18s\n", "node", "node->next", "node->prev"); 
         node *current = list_ptr->head; 
         do { 
          printf(PTR_FMT " " PTR_FMT " " PTR_FMT "\n", 
            (uintptr_t) current, 
            (uintptr_t) current->next, 
            (uintptr_t) current->prev); 
          current = current->next; 
         } while (current != NULL); 
        } 
        unlock(&list_ptr->mutex); 
    } 
    
    int main(void) { 
        list *linked_list = list_init(); 
    
        printf("Add items...\n"); 
        for (int value = 1; value <= 3; value++) { 
         list_add(linked_list, value); 
         list_print(linked_list); 
        } 
    
        printf("Remove items...\n"); 
        while (1) { 
         node *result = list_remove(linked_list); 
         if (NULL == result) { 
          break; 
         } 
         free(result); 
         list_print(linked_list); 
        } 
    
        if ((linked_list->head != NULL) || (linked_list->tail != NULL)) { 
         printf("ERROR: List is not empty\n"); 
         return EFAULT; 
        } 
    
        free(linked_list); 
    
        return 0; 
    } 
    

    出力

    Add items... 
    ---------- 
    length = 1 
    list    list->head   list->tail   
    0x00007F8180C031B0 0x00007F8180C0x00007F8180C
    node    node->next   node->prev   
    0x00007F8180C0x0000000000000000 0x0000000000000000 
    ---------- 
    length = 2 
    list    list->head   list->tail   
    0x00007F8180C031B0 0x00007F8180C0x00007F8180C03230 
    node    node->next   node->prev   
    0x00007F8180C0x00007F8180C03230 0x0000000000000000 
    0x00007F8180C03230 0x0000000000000000 0x00007F8180C
    ---------- 
    length = 3 
    list    list->head   list->tail   
    0x00007F8180C031B0 0x00007F8180C0x00007F8180C03250 
    node    node->next   node->prev   
    0x00007F8180C0x00007F8180C03230 0x0000000000000000 
    0x00007F8180C03230 0x00007F8180C03250 0x00007F8180C
    0x00007F8180C03250 0x0000000000000000 0x00007F8180C03230 
    Remove items... 
    ---------- 
    length = 2 
    list    list->head   list->tail   
    0x00007F8180C031B0 0x00007F8180C0x00007F8180C03230 
    node    node->next   node->prev   
    0x00007F8180C0x00007F8180C03230 0x0000000000000000 
    0x00007F8180C03230 0x0000000000000000 0x00007F8180C
    ---------- 
    length = 1 
    list    list->head   list->tail   
    0x00007F8180C031B0 0x00007F8180C0x00007F8180C
    node    node->next   node->prev   
    0x00007F8180C0x0000000000000000 0x0000000000000000 
    ---------- 
    length = 0 
    list    list->head   list->tail   
    0x00007F8180C031B0 0x0000000000000000 0x0000000000000000 
    

    私は自分のリストの扱いを修正するために、デバッガを使用していました。私はあなたの問題を解決するために1つを使うことをお勧めします

    +0

    私はinitlist_destroy関数を実行しようとしましたが、なぜエラーが発生するのかわかりません。 – lippy1234

    +0

    はい、要素をリストに追加するときや、リストから要素を削除するときに間違ったことをしています。あなたのリストの最後の要素の 'next'ポインタは' NULL'でなければなりません。代わりに、リストの最後の要素を指します。デバッガでリスト処理コードをステップ実行することで問題を確認できるはずです。 –

    +0

    私はコード内でそれを変更しましたが、答えがダウンしています。しかし、10人のライター、10人の読者、10人のmeaxサイズ、100秒のコードを実行すると、initlist_pop_tail関数のcond_waitどうして? – lippy1234