您的位置:首页 > 其它

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

2017-03-10 22:16 316 查看
多线程真的能加速程序的执行吗?

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

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,内存等各种资源也是不容小视地,一些比较简单地事务,还是老老实实地用单线程吧,这样自己还轻松一点,不用考虑多线程带来的各种问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程