C小程序 - 分析一个多线程的小程序
来源:互联网 发布:淘宝购物评级怎么掉了 编辑:程序博客网 时间:2024/04/28 21:00
C小程序 - 分析一个多线程的小程序 (2012-11-01 11:51)
分类: Linux C
这个程序的作用是统计输入的两个文件的字数,使用方法
./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[1];
- args1.count = 0;
- args1.name = "1";
- pthread_create(&t1, NULL, count_words, (void *) &args1); //开启第一个线程
- args2.fname = av[2];
- 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: oops..mailbox 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);
- //的时候,主线程释放了锁,子线程才能对互斥量继续加锁,从而继续执行。
- }
- mailbox = args; /* put ptr to our args there */
- printf("COUNT%s: raising flag\n", args->name);
- pthread_cond_signal(&flag); //通知主线程信号变化
- printf("COUNT%s: unlocking box\n", args->name);
- pthread_mutex_unlock(&lock); //释放锁。
- printf("COUNT%s: unlocked box\n", args->name);
- return NULL;
- }
- [lizhuohua@lizhuohua-phy Program]$ ./program cp1.c cp2.c
- COUNT1: waiting to get lock
- COUNT2: waiting to get lock
- MAIN: waiting for flag to go up
- COUNT1: have lock, storing data
- COUNT1: raising flag
- COUNT1: unlocking box
- COUNT1: unlocked box
- MAIN: flag was raised, I have the lock
- 131: cp1.c
- MAIN: waiting for flag to go up
- COUNT2: have lock, storing data
- COUNT2: raising flag
- COUNT2: unlocking box
- COUNT2: unlocked box
- MAIN: flag was raised, I have the lock
- 131: cp2.c
- 262: total word
- C小程序 - 分析一个多线程的小程序
- 多线程实现的一个小程序
- 分析一个小程序的实现
- 关于C语言的一个小程序
- 一个简单的C语言小程序
- c的小程序
- 一个C语言小程序
- C#/.net学习-13-一个多线程的摇奖winform小程序
- 利用多线程加速程序的小程序
- C/C++拾遗录--关于一个C语言小程序的分析
- C/C++拾遗录--关于一个C语言小程序的分析
- 一个有意思的小程序,考验多线程问题能力
- Linux下C语言多线程小程序
- 一个小程序的小BUG
- 一个XmlHttpRequest的小程序
- jsf的一个小程序
- jetty的一个小程序
- 一个无聊的小程序
- 用C语言检测文本编码的方法
- .so动态库的制作
- Windows Phone 8 开发笔记
- java.util.Collections使用说明
- 21世纪需要的七种人才—李开复
- C小程序 - 分析一个多线程的小程序
- JS获取当前时间戳的方法 QQ 253079952
- jquery的extend和fn.extend的使用说明
- SVN commit:remains in tree-conflict错误的解决办法
- 僵尸进程
- 单例设计模式Singleton
- Can I use iPad/iPhone with SharePoint 2010?
- C++构造函数 参数列表的执行顺序 从右向左啊。。。
- DDX、DRM和DRI是什么