Design - multithreading word count tool
1, experiments show that
there are two text files file1.txt, file2.txt, then count the number of words in the two documents.
2, solutions
distinguish the word principle: whatever a non behind the letters or numbers, then the letter or number that ends with the letter or numeric characters with words. Allowing threads to use mutex to modify the critical resources to ensure synchronization and collaboration between threads. If two threads need to share a common counter safely, you need to lock the public counter. Threads need to access the variable called mutex, it can make a good cooperation between the threads, to avoid access conflicts for resources.
Code
#include <stdio.h>
#include <pthread.h>
#include <ctype.h>
#include <stdlib.h>
//互斥信号量
pthread_mutexattr_t counter_clock;
//公共计数器
int total_word = 0;
// 线程函数,即统计一个文件的单词个数函数
void *count_words(void *f)
{
char *filename = (char *)f;
FILE *fp;
int c;
int prevc = '\0';
if((fp=fopen(filename,"r"))!=NULL)
{
while((c=getc(fp))!=EOF)
{
//isalnum()用来判断一个字符是否为数字或者字母,也就是说判断一个字符是否属于a~z||A~Z||0~9,是返回非0。
if(!isalnum(c)&&isalnum(prevc))
{
pthread_mutex_lock(&counter_clock);// 线程加锁
total_word++;
pthread_mutex_unlock(&counter_clock);//线程解锁
}
prevc = c;
}
fclose(fp);
}
//打开失败
else
{
perror(filename);
}
return NULL;
}
/*argcargc = argument count :表示传入main函数的数组元素个数,为int类型,
而 argv = argument vector :表示传入main函数的指针数组,为char*类型。
第一个数组元素argv[0]是程序名称,并且包含程序所在的完整路径。argc至少为1,即
argv数组至少包含程序名。*/
//本个程序,由于是两个文件,main函数需要传入两个参数,由于计入本身程序,所以argc=3,
int main(int argc,char*argv[])
{
// 调试格式,
if(argc!=3)
{
printf("Usage:%s file1 file2\n",argv[0]);
exit(1);
}
// 线程t1,t2
pthread_t t1,t2;
int res;
// 初始化临界区
res = pthread_mutex_init(&counter_clock,NULL);
if(res!=0)
{
perror("Mutex initialization failed\n");
exit(EXIT_FAILURE);
}
/*int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn)(void*),void *restrict arg);
创建线程1
第一个参数为指向线程标识符的指针。
第二个参数用来设置线程属性。
第三个参数是线程运行函数的起始地址。
最后一个参数是运行函数的参数。*/
res = pthread_create(&t1,NULL,count_words,argv[1]);
printf(" Thread 01 creating...\n");
if(res!=0)
{
perror("Thread create failly\n");
exit(EXIT_FAILURE);
}
else
{
printf(" Thread 01 create successfully!\n");
}
// 创建线程2
res = pthread_create(&t2,NULL,count_words,argv[2]);
printf(" Thread 02 creating...\n");
if(res!=0)
{
perror("Thread create failly\n");
exit(EXIT_FAILURE);
}
else
{
printf(" Thread 02 create successfully!\n");
}
// 让线程1进入等待态
res = pthread_join(t1,NULL);
printf(" Thread 01 joinning...\n");
if(res!=0)
{
perror("Thread join failly\n");
exit(EXIT_FAILURE);
}
else
{
printf(" Thread 01 joined successfully!\n");
}
// 让线程2进入等待态
res = pthread_join(t2,NULL);
printf(" Thread 02 joinning...\n");
if(res!=0)
{
perror("Thread join failly\n");
exit(EXIT_FAILURE);
}
else
{
printf(" Thread 02 joined successfully!\n");
}
// 输出统计出来的单词总数
printf("There are %d words in two files\n",total_word);
pthread_mutex_destroy(&counter_clock);
return 0;
}
operation result:
Reference link
1, thread_create Detailed functions: https://blog.csdn.net/zhou1021jian/article/details/71514738
2, thread_join Detailed functions: https: //blog.csdn.net/yzy1103203312/article/details/80849831pthread_join()函数原型: int pthread_join(pthread_t thread, void **retval); args: pthread_t thread: 被连接线程的线程号 void **retval : 指向一个指向被连接线程的返回码的指针的指针 return: 线程连接的状态,0是成功,非0是失败
When you call pthread_join (), the current thread is blocked until after the end of the thread is called, the current (main) thread will resume execution. When pthread_join () function returns, the calling thread is considered the end in the true sense, its memory space is freed (if the calling thread is non-isolated). Here are three things to note:
1, was released memory space is only space systems, you must manually clear the space allocated to the program, such as malloc () space allocation.
2, a thread can be connected to a thread.
3, connected by the thread must be non-isolated, or the connection will be wrong.
It can be seen pthread_join () has two effects:
- Waiting for the other end of the thread: When you call pthread_join (), the current thread is blocked until after the end of the thread is called, the current thread will resume execution.
- Thread resources for recycling: If a thread is non-isolated (threads created by default are non-isolated) and does not use pthread_join the thread (), then after the end of the thread does not release its memory space, which can lead to this thread has become a "zombie thread."