CS162 操作系统HW2(使用Liunx内核链表以及多线程实现WordCounter)

心得体会

IDE自动提示补全真的特别重要,大大提高开发效率。通过IDE自动搜索库函数API。

GDB调试能力要加强。

 

使用前面提供的list.h来改写wordCount程序,头文件的实现相当有技巧,将使用外部list库,多线程都用宏定义到同一份代码中,这是C/C++开发的常用技巧。

这里Linux内核里面的链表实现和传统的有一些区别

word_count.h

#ifdef PINTOS_LIST
#include "list.h"
typedef struct word_count {
  char* word;
  int count;
  struct list_elem elem;
} word_count_t;

#ifdef PTHREADS
#include <pthread.h>
typedef struct word_count_list {
  struct list lst;
  pthread_mutex_t lock;
} word_count_list_t;
#else  /* PTHREADS */
typedef struct list word_count_list_t;
#endif /* PTHREADS */

#else  /* PINTOS_LIST */

typedef struct word_count {
  char* word;
  int count;
  struct word_count* next;
} word_count_t;

typedef word_count_t* word_count_list_t;
#endif /* PINTOS_LIST */

/* Initialize a word count list. */
void init_words(word_count_list_t* wclist);

/* Get length of a word count list. */
size_t len_words(word_count_list_t* wclist);

/* Find a word in a word_count list. */
word_count_t* find_word(word_count_list_t* wclist, char* word);

/*
 * Insert word with count=1, if not already present; increment count if
 * present. Takes ownership of word.
 */
word_count_t* add_word(word_count_list_t* wclist, char* word);

/* Print word counts to a file. */
void fprint_words(word_count_list_t* wclist, FILE* outfile);

/* Sort a word count list using the provided comparator function. */
void wordcount_sort(word_count_list_t* wclist, bool less(const word_count_t*, const word_count_t*));

#endif /* WORD_COUNT_H */

word_count_l.c  单线程的实现

#ifndef PINTOS_LIST
#error "PINTOS_LIST must be #define'd when compiling word_count_l.c"
#endif

#include "word_count.h"

void init_words(word_count_list_t* wclist) {
  list_init(wclist);
  return;
}

size_t len_words(word_count_list_t* wclist) {
  return list_size(wclist);
}

word_count_t* find_word(word_count_list_t* wclist, char* word) {
  struct list_elem *e;
  for(e=list_begin(wclist);e!=list_end(wclist);e=list_next(e)){
    word_count_t* p = list_entry(e,word_count_t, elem);
    if(strcmp(p->word,word)==0){
      return p;
    }
  }
  return NULL;
}

word_count_t* add_word(word_count_list_t* wclist, char* word) {
  word_count_t* p = find_word(wclist,word);
  if(p!=NULL){
    p->count++;
    return p;
  }
  word_count_t* tmp = (word_count_t*)malloc(sizeof(word_count_t));
  tmp->count = 1;
  tmp->word = word; 
  list_push_back(wclist,&tmp->elem);
  return tmp;
}

void fprint_words(word_count_list_t* wclist, FILE* outfile) {
  struct list_elem *e;
  for (e = list_begin (wclist); e != list_end(wclist);e = list_next (e)){
    word_count_t *wc = list_entry(e, word_count_t, elem);
    fprintf(outfile, "%8d\t%s\n", wc->count, wc->word);
  }
}

static bool less_list(const struct list_elem* ewc1, const struct list_elem* ewc2, void* aux) {
  /* TODO */
  bool (*less)(const word_count_t *, const word_count_t *) = aux;
  word_count_t *wc1 = list_entry(ewc1, word_count_t, elem);
  word_count_t *wc2 = list_entry(ewc2, word_count_t, elem);
  return less(wc1, wc2);
}

void wordcount_sort(word_count_list_t* wclist,
                    bool less(const word_count_t*, const word_count_t*)) {
  list_sort(wclist, less_list, less);
}

多线程的实现很简单,在插入时保证线程完全,加锁即可。注意结构体的定义发生改变。

#ifndef PINTOS_LIST
#error "PINTOS_LIST must be #define'd when compiling word_count_lp.c"
#endif

#ifndef PTHREADS
#error "PTHREADS must be #define'd when compiling word_count_lp.c"
#endif

#include "word_count.h"

void init_words(word_count_list_t* wclist) {
  list_init(&wclist->lst);
  pthread_mutex_init(&wclist->lock, NULL);
}

size_t len_words(word_count_list_t* wclist) {
  return list_size(&wclist->lst);
}

word_count_t* find_word(word_count_list_t* wclist, char* word) {
  struct list_elem *e;
  for(e=list_begin(&wclist->lst);e!=list_end(&wclist->lst);e=list_next(e)){
    word_count_t* p = list_entry(e,word_count_t, elem);
    if(strcmp(p->word,word)==0){
      return p;
    }
  }
  return NULL;
}

word_count_t* add_word(word_count_list_t* wclist, char* word) {
  pthread_mutex_lock(&wclist->lock);
  word_count_t* p = find_word(wclist,word);
  if(p!=NULL){
    p->count++;
  }else{
    p = (word_count_t*)malloc(sizeof(word_count_t));
    p->count = 1;
    p->word = word;
    list_push_front(&wclist->lst,&p->elem);
  }
  pthread_mutex_unlock(&wclist->lock);
  return p;
}

void fprint_words(word_count_list_t* wclist, FILE* outfile) { /* TODO */
  struct list_elem *e;
  for (e = list_begin(&wclist->lst);e!=list_end(&wclist->lst);e=list_next(e)){
    word_count_t *wc = list_entry(e, word_count_t, elem);
    fprintf(outfile, "%8d\t%s\n", wc->count, wc->word);
  }
}

static bool less_list(const struct list_elem* ewc1, const struct list_elem* ewc2, void* aux) {
  /* TODO */
  bool (*less)(const word_count_t *, const word_count_t *) = aux;
  word_count_t *wc1 = list_entry(ewc1, word_count_t, elem);
  word_count_t *wc2 = list_entry(ewc2, word_count_t, elem);
  return less(wc1, wc2);
}

void wordcount_sort(word_count_list_t* wclist,
                    bool less(const word_count_t*, const word_count_t*)) {
  list_sort(&wclist->lst, less_list, less);
}

在来看一遍主函数

typedef struct thread_word_args
{
  word_count_list_t* word_counts;
  char* filename;
} targs_t;

void *threadfun(void *arg) {
  targs_t* targs = (targs_t*)arg;
  FILE *infile = fopen(targs->filename, "r");
  if (infile == NULL) {
    perror("fopen");
    pthread_exit(NULL);
  }
  // pthread_mutex_lock(&targs->word_counts->lock);
  count_words(targs->word_counts, infile);
  // pthread_mutex_unlock(&targs->word_counts->lock);
  fclose(infile);
  pthread_exit(NULL);
}

/*
 * main - handle command line, spawning one thread per file.
 */
int main(int argc, char* argv[]) {
  /* Create the empty data structure. */
  word_count_list_t word_counts;
  init_words(&word_counts);

  if (argc <= 1) {
    /* Process stdin in a single thread. */
    count_words(&word_counts, stdin);
  } else {
    int nthreads = argc - 1;
    pthread_t threads[nthreads];
    for(int i=0;i<nthreads;i++){
      targs_t* targs = (targs_t *) malloc(sizeof(targs_t));
      targs->filename = argv[i+1];
      targs->word_counts = &word_counts;
      int rc = pthread_create(&threads[i], NULL, threadfun, (void *)targs);
      if(rc){
        printf("ERROR; return code from pthread_create() is %d\n", rc);
        exit(-1);
      }
    }
    for(int i=0;i<nthreads;i++){
      pthread_join(threads[i],NULL);
    }
  }

  /* Output final result of all threads' work. */
  wordcount_sort(&word_counts, less_count);
  fprint_words(&word_counts, stdout);
  pthread_exit(NULL);
  return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值