关于多线程对程序执行时间的影响

    xiaoxiao2021-03-25  113

    多线程真的能加速程序的执行吗?

    假设有以下一个任务:读取一个文件,从文件中搜索指定的单词,统计个数。用以下两种方式完成:

    1.开两个线程,一个线程负责读取文件,读取一个单词后扔给另一个线程,另一个线程负责检查这个单词是否匹配指定的单词。

    2.只用一个线程,边读文件,读完一个单词以后,匹配这个单词,匹配出结果以后再读下一个单词。

    两段程序的代码如下:

    多线程程序:(文本文件用的是我在申请的 Binghamton University 的personal statement复制30变以后的结果,所以选择匹配的单词是Binghamton, Orz)(顺便学习一下多线程参数的传递,要将scan_file文件扫描线程扫到的单词传到cmp单词匹配线程中去,LPVOID是一个可以指向任意结构体的指针,可以把自己想传的参数全部写到里面去,就实现了线程之间参数的传递)

    #include "stdafx.h" #include <stdio.h> #include <windows.h> #include <string.h> #include <iostream> #include <time.h> int cnt = 0, tcnt = 0; struct p_type { char content[30]; }; DWORD WINAPI cmp(LPVOID p) { p_type *pmsg; pmsg = (p_type*)(p); if (strcmp(pmsg->content, "Binghamton") == 0) { cnt++; } return 0; } DWORD WINAPI scan_file(LPVOID p) { p_type *pmsg; DWORD cmp_id, cmp_excode; FILE *fp; HANDLE cmph; char strget[20]; fp = fopen("D:\\testdata.txt", "r"); if (fp == NULL) { printf("fopen failed\n"); } else { while (fscanf(fp, "%s", strget) != EOF) { pmsg = (p_type*)malloc(sizeof(p_type)); strcpy(pmsg->content, strget); CreateThread(NULL, 0, cmp, pmsg, 0, &cmp_id); } } fclose(fp); return 0; } int main(int argc, char* argv[]) { HANDLE scanh; DWORD scan_id, scan_excode, start_time, end_time; time_t start, stop; start = time(NULL); scanh = CreateThread(NULL, 0, scan_file, 0, 0, &scan_id); start_time = GetTickCount(); cnt = 0; scanh = CreateThread(NULL, 0, scan_file, 0, 0, &scan_id); while (1) { if (cnt >= 1888) { break; } } end_time = GetTickCount(); printf("一共有:%d 个\n", cnt); printf("一共用时: %d ms\n", end_time - start_time); return 0; }单线程程序1如下:

    #include "stdafx.h" #include <string.h> #include <stdio.h> #include <time.h> #include <windows.h> int cnt; int main(int argc, char* argv[]) { char getstr[30]; FILE *fp; DWORD start_time, end_time; start_time = GetTickCount(); cnt = 0; fp = fopen("D:\\testdata.txt", "r"); if (fp == NULL) { printf("fopen failed\n"); } else { while (fscanf(fp, "%s", getstr) != EOF) { if (strcmp(getstr, "Binghamton") == 0) { cnt++; } } } end_time = GetTickCount(); printf("一共有 %d 个\n", cnt); printf("一共用时 %d ms\n", end_time - start_time); return 0; } 执行的结果分别如下:

    多线程程序:

    单线程程序1:

    可以看到,单线程程序竟然远远优于多线程的程序!

    我推测是由于开启线程,销毁线程本身会占用大量的时间。所以为了公平期间,我让单线程程序依然开一个扫描文件线程,一个比较单词线程,只不过这两个线程轮流串行执行(通过GetExitCodeThread()函数判断上一个线程是否已经结束),于是有了单线程程序2。

    单线程程序2:

    #include "stdafx.h" #include <windows.h> #include <string.h> #include <iostream> #include <time.h> int cnt; struct p_type { char content[30]; }; DWORD WINAPI cmp(LPVOID p) { p_type *pmsg; pmsg = (p_type*)(p); if (strcmp(pmsg->content, "Binghamton") == 0) { cnt++; } return 0; } DWORD WINAPI scan_file(LPVOID p) { p_type *pmsg; DWORD cmp_id, cmp_excode; FILE *fp; HANDLE cmph; char strget[20]; fp = fopen("D:\\testdata.txt", "r"); if (fp == NULL) { printf("fopen failed\n"); } else { while (fscanf(fp, "%s", strget) != EOF) { pmsg = (p_type*)malloc(sizeof(p_type)); strcpy(pmsg->content, strget); cmph = CreateThread(NULL, 0, cmp, pmsg, 0, &cmp_id); while (1) { GetExitCodeThread(cmph, &cmp_excode); if (cmp_excode != STILL_ACTIVE) { break; } } } } fclose(fp); return 0; } int main(int argc, char* argv[]) { DWORD scan_file_id,scan_file_excode; int *unused1, *unused2; HANDLE scan_file_h; FILE *fp; DWORD start_time, end_time; start_time = GetTickCount(); char strget[30]; unused1 = (int*)malloc(sizeof(30)); unused2 = (int*)malloc(sizeof(30)); cnt = 0; fp = fopen("D:\\testdata.txt", "r"); if (fp == NULL) { printf("fopen failed\n"); } else { scan_file_h=CreateThread(NULL, 0, scan_file, 0, 0, &scan_file_id); while (1) { GetExitCodeThread(scan_file_h, &scan_file_excode); if (scan_file_excode != STILL_ACTIVE) { break; } } } end_time = GetTickCount(); printf("一共有:%d 个\n", cnt); printf("一共用时:%d ms\n", end_time - start_time); return 0; }

    执行结果如下:

    可以看到,这下,单线程就远远不如多线程程序了。

    于是可以总结如下:多线程确实有它的好处,比如之前Android开发中可以看到,可以用一个线程来处理用户界面,另一个线程到后台去读数据,避免在读数据的时候给用户造成“死机”的假象。

    但也不能盲目地使用多线程,多线程中启动线程,销毁线程以及占用地CPU,内存等各种资源也是不容小视地,一些比较简单地事务,还是老老实实地用单线程吧,这样自己还轻松一点,不用考虑多线程带来的各种问题。

    转载请注明原文地址: https://ju.6miu.com/read-24972.html

    最新回复(0)