设为首页 加入收藏

TOP

C小程序 - 分析一个多线程的小程序(一)
2012-11-03 14:23:28 来源: 作者: 【 】 浏览:1910
Tags:程序   分析 一个 线程

  这个程序的作用是统计输入的两个文件的字数,使用方法
  
  ./program cp1.c cp2.c
  
  /* threaded word counter for two files.
  
  */
  
  #include <stdio.h>
  
  #include <pthread.h>
  
  #include <ctype.h>
  
  struct arg_set {
  
  char *fname;    //文件名
  
  int count;    //文字数量
  
  char *name;   //线程名字
  
  };
  
  struct arg_set *mailbox = NULL;
  
  pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
  
  pthread_cond_t flag = PTHREAD_COND_INITIALIZER;
  
  main(int ac, char *av[])
  
  {
  
  pthread_t t1, t2;        /* two threads */
  
  struct arg_set args1, args2;    /* two argsets */
  
  void     *count_words(void *);
  
  int reports_in = 0;
  
  int     total_words = 0;
  
  if ( ac != 3 ){
  
  printf(“usage: %s file1 file2\n”, av[0]);
  
  exit(1);
  
  }
  
  pthread_mutex_lock(&lock);    // 对互斥量加锁
  
  args1.fname = av ;
  
  args1.count = 0;
  
  args1.name = “1”;
  
  pthread_create(&t1, NULL, count_words, (void *) &args1); //开启第一个线程
  
  args2.fname = av ;
  
  args2.count = 0;
  
  args2.name = “2”;
  
  pthread_create(&t2, NULL, count_words, (void *) &args2); //开启第二个线程
  
  /* sleep(10); */ //这里通过sleep函数来检查一下对同一个lock加锁多次的现象,
  
  //在本人的机器上,主线程sleep的时候,
  
  //子线程们会pending在线程函数对互斥量加锁的地方;也就是count_words中的第17行的地方。
  
  while( reports_in < 2 ){
  
  printf(“MAIN: waiting for flag to go up\n”);
  
  pthread_cond_wait(&flag, &lock); //pthread_cond_wait的作用是
  
  //1.先释放锁
  
  //2.等待信号flag的变化
  
  //3.当收到信号变更通知的时候被唤醒,再次对互斥量加锁
  
  printf(“MAIN: Wow! flag was raised, I have the lock\n”);
  
  printf(“%7d: %s\n”, mailbox->count, mailbox->fname);
  
  total_words += mailbox->count;
  
  if ( mailbox == &args1)
  
  pthread_join(t1,NULL);
  
  if ( mailbox == &args2)
  
  pthread_join(t2,NULL);
  
  mailbox = NULL;
  
  pthread_cond_signal(&flag);        // 告知信号有变化,如果没有线程在等待信号变化,
  
  //那么不会发生什么,如果有线程在等待信号,那么该线程被唤醒
  
  reports_in++;
  
  }
  
  printf(“%7d: total words\n”, total_words);
  
  }
  
  void *count_words(void *a)
  
  {
  
  struct arg_set *args = a;    /* cast arg back to correct type */
  
  FILE *fp;
  
  int c, prevc = '\0';
  
  if ( (fp = fopen(args->fname, “r”)) != NULL ){
  
  while( ( c = getc(fp)) != EOF ){
  
  if ( !isalnum(c) && isalnum(prevc) )
  
  args->count++;
  
  prevc = c;
  
  }
  
  fclose(fp);
  
  } else
  
  perror(args->fname);
  
  printf(“COUNT%s: waiting to get lock\n”, args->name);
  
  pthread_mutex_lock(&lock);    //子线程对互斥量加锁
  
  printf(“COUNT%s: have lock, storing data\n”, args->name);
  
  if ( mailbox != NULL ){ //如果mailbox不为空,这种情况出现在第一个子线程结束后,
  
  //第二个子线程马上获得锁,并开始执行,
  
  //而主线程此时虽然已经获得信号变化通知,
  
  //但是被其它子线程抢先对互斥量加锁并执行。
  
  //这样主线程的pthread_cond_wait(&flag, &lock);就无法对互斥量加锁,
  
  //pthread_cond_wait(&flag, &lock);函数不能返回,继续等待。
  
  printf(“COUNT%s: oopsmailbox not empty. wait for signal\n”, args->name);
  
  pthread_cond_wait(&flag,&lock); //而当第二个子线程执行到这里发现mailbox不为空的时候,它执行                                                 //pthread_cond_wait(&flag, &lock);函数,
  
  //这个函数首先释放锁,并等待信号变化
  
  //此时,主线程的pthread_cond_wait(&flag, &lock);才能对互斥量加锁,
  
  //从而返回,继续执行。
  
  //而这里第二个子线程将等待主线程pthread_cond_signal(&flag);
  
  //函数的执行,从而获取信号变化通知,
  
  //然后主线程的while循环到再次执行pthread_cond_wait(&flag, &lock);
  
  //的时候,主线程释放了锁,子线程才能对互斥量继续加锁,从而继续执行。
  
  }

   

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 1/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C语言 内存管理详解 下一篇C小程序 - 信号量

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: