操作系统原理课程设计——多线程实现单词统计工具实验

[设计目的]

1. 学习并掌握多线程编程的基本概念和技巧;

2. 理解并应用互斥锁(mutex)来同步线程间的操作;

3. 设计并实现一个能够并行处理文件的单词统计工具。

[设计要求]

在操作系统当中,实现一个多线程程序,能够同时对两个文本文件进行单词统计。

在操作系统中,确保线程安全,避免在统计过程中出现数据竞争。

[设计思想及内容]

设计思想是通过创建两个线程,每个线程负责读取并统计一个文件中的单词数量。使用互斥锁来同步对共享变量total的访问,确保统计结果的正确性。

[数据结构设计]

total_words: 用于存储两个文件中单词总数的全局变量。

counter_clock: 互斥锁,用于同步对total变量的访问

total:用于存储统计总的文件中的单词总数的全局变量

补充命令

可能有的小伙伴不记得一些命令了,这里我稍微写一下(以我的文件world_total为例)

vim word_total.c   还有两个文本文件:vim word1.txt 和vim word2.txt

gcc word_total.c -o word_total

./word_total ./word1.txt ./word2.txt 

[程序源码]

#include <stdio.h>

#include <pthread.h>//POSIX线程库,用于创建和管理线程

//字符串类型函数库,用于判断字符是否为字母或者数字

#include <ctype.h>        

#include <stdlib.h>   //标准库,提供一些通用函数,如exit()



//用于统计总的单词数

int total=0;



//定义互斥锁

//声明并初始化一个互斥锁,用于同步对total_words变量的访问。

pthread_mutex_t counter_clock=PTHREAD_MUTEX_INITIALIZER;



int main(int ac,char *av[])

{

  void *count_words(void *);

//如果参数个数不等于三个,则打印提示后退出程序

//三个是因为程序名、两个文件名

  if(ac!=3)

  {

    printf("Usage:%s file1 file2\n",av[0]);

    exit(1);

  }

//创建两个线程tidp1和tidp2,分别用于处理两个文件的单词统计

  pthread_t tidp1,tidp2;

  int e1,e2;

 //建立两个线程tidp1 tidp2

  e1=pthread_create(&tidp1,NULL,count_words,av[1]);

  e2=pthread_create(&tidp2,NULL,count_words,av[2]);



//使用pthread_join等待两个线程完成。

//让线程tidp1和tidp2进入等待状态

  pthread_join(tidp1,NULL);

  pthread_join(tidp2,NULL);

  printf(“\n”);

printf(“total = %d”,total);

  return 0;

}



//这是一个线程函数,由main函数中的pthread_create调用

void *count_words(void *f)

{

  char *filename=(char *)f;

  FILE *fp;

  int c,prevc='\0';

  int total_words=0;

  if((fp=fopen(filename,"r"))!=NULL){

    while((c=getc(fp))!=EOF)

{

//使用isalnum函数判断字符是否为字母或数字

      if(!isalnum(c) && isalnum(prevc)){



//当遇到一个非字母数字字符且前一个字符是字母数字时,认为发现了一个单词//的边界。此时:

//1使用pthread_mutex_lock锁定互斥锁,以确保线程安全地增加单词计数。

//2增加total_words计数。

//3使用pthread_mutex_unlock解锁互斥锁(类似于pv原语)

         pthread_mutex_lock(&counter_clock);

         total_words++;

         pthread_mutex_unlock(&counter_clock);

       }

       prevc=c;

    }

    fclose(fp);

printf("total_words=%d\n",total_words);



pthread_mutex_lock(&counter_clock);

total+=total_words;

pthread_mutex_unlock(&counter_clock);

  }else{

        perror(filename);

  }

  return NULL;

}

[设计实现展示(附截图说明)]

Word1.txt文件中的内容

Word2.txt文件中的内容

编译链接并执行程序,我们可以看到文件一中有222个单词,文件二中有346个单词

改进之后加了个总的计数器

总的单词数为568

[课程设计出现问题及解决方法]

遇到的问题:

1互斥锁使用不当

问题:在count_words函数中,第一次使用互斥锁是将一个文件中的所有单词都统计完成才会放开,这样会造成一个进程统计,而另一个进程只能等待的现象,就算被统计的进程暂时空闲,也不会放开互斥锁,造成志愿的浪费

解决方法:

在每一个统计时都加锁,既保证了文件的安全性,互斥型号量不会被随意更改,又使得CPU不会空闲,充分利用CPU资源

【参考资料】

[1] https://blog.csdn.net/zmxiangde_88/article/details/7998458

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值