搜档网
当前位置:搜档网 › 实验一 :WindowsThreads多线程编程

实验一 :WindowsThreads多线程编程

实验一 :WindowsThreads多线程编程
实验一 :WindowsThreads多线程编程

实验一:Windows*Threads多线程编程模块一:基础练习

4 编译执行,输出结果:

简答与思考:

1写出修改后的HelloThreads的代码。

#include "stdafx.h"

#include

const int numThreads = 4;

DWORD WINAPI helloFunc(LPVOID pArg)

{

int myNum=*((int*)pArg);

printf("Hello Thread %d \n",myNum);

return 0;

}

int main()

{

HANDLE hThread[numThreads];

int tNum[10];

for (int i = 0; i < numThreads; i++)

{ tNum[i]=i;

hThread[i] =

CreateThread(NULL, 0, helloFunc, &tNum[i], 0, NULL );

}WaitForMultipleObjects(numThreads, hThread, TRUE, INFINITE);

return 0;

}

修改后结果

2实验总结

模块二:临界区实验

2编译执行,Pi的值为:

3编译执行,Pi的值为:

简答与思考:

1 如何进行并行化的?请写出并行化的思路与具体的代码。// WinPi.cpp : 定义控制台应用程序的入口点

//

#include "stdafx.h"

#include

#include

static long num_steps=1000000000;

double step, pi;

CRITICAL_SECTION gCS; //定义全局的临界变量gCS

const int numThreads = 2;

double dAllSum;

DWORD WINAPI PiCalculationThread(LPVOID p)

{

int j = *(int *)p;

double dSum = 0;

double dx;

int ii;

printf("This is the thread %d computing:\n",j);

for( ii = j ; ii < num_steps ; ii+=numThreads ){

dx = (ii+0.5)*step;

dSum = dSum + 4.0/(1.0 + dx*dx);

}

EnterCriticalSection(&gCS); //进入临界区

dAllSum += dSum;

LeaveCriticalSection(&gCS); //离开临界区

printf("The thread %d computation has finished:\n",j);

return 0;

}

int _tmain(int argc, _TCHAR* argv[])

{

clock_t start1;

clock_t stop1;

start1= clock(); //开始计时

HANDLE PiCalculation[numThreads];

int tmp[numThreads];

step = 1.0/(double) num_steps;

InitializeCriticalSection(&gCS);

for( int ia = 0 ; ia < numThreads ; ia++ ){

tmp[ia] = ia;

PiCalculation[ia] = CreateThread(NULL , 0 , PiCalculationThread , &tmp[ia] , 0 , NULL);

}

WaitForMultipleObjects (numThreads,PiCalculation,TRUE,INFINITE);

DeleteCriticalSection(&gCS);

pi = step * dAllSum;

printf("Pi = %12.9f\n",pi);

stop1 = clock(); //停止计时

printf("The time of calculation was %f seconds \n",(double)(stop1 - start1)/1000.0);

//输出运行时间

}

2 在本实验中,哪些变量是需要保护的?采取什么方法实现的?

dAllSum变量需要保护

EnterCriticalSection(&gCS); //进入临界区

dAllSum += dSum;

LeaveCriticalSection(&gCS); //离开临界区

printf("The thread %d computation has finished:\n",j);

3是否可以对该并行化方案进行进一步的优化?如何优化?

更改不同的线程数,计算加速比和效率,结果最好的那个线程数作为程序运行的最佳线程数4 实验总结

模块三:事件实验

3 编译执行,Result is

The time of calculation was 19.55700seconds 4阅读代码,回答下面问题。

(1)主线程共创建 2 个子线程。

(2)各子线程调用的函数各是什么?

Count threadProc

(3)主线程等待 2 个子线程的执行结束。

6 改进后的,编译执行,Result

is

The time of calculation was 15.122000 seconds

简答与思考:

1 在WINAPI threadProc(LPVOID par){}函数中为什么用临界区互斥了线程对threadCount的访问?为什么对于全局数据变量sums的访问没有互斥?

WINAPI threadProc(LPVOID par){}函数使用多线程执行的threadCount 对于WINAPI threadProc(LPVOID par){}函数是共享变量,如果不使用临界区互斥了线程对threadCount 的访问会造成数据冲突。

2 简述源代码中存在的问题,详述提出的改进方案及相关代码。

// ThreadEvent.cpp : 定义控制台应用程序的入口点

//

#include "stdafx.h"

#include

#include

#include

#include

#include

#define NUMTHREADS 4

#define SERIES_MEMBER_COUNT 100000

HANDLE *threadHandles, masterThreadHandle,*eventHandle;

CRITICAL_SECTION countCS;

double *sums;

double x = 1.0, res = 0.0;

int threadCount = 0;

double getMember(int n, double x)

{

double numerator = 1;

for( int i=0; i

numerator = numerator*x;

if ( n % 2 == 0 )

return ( - numerator / n );

else

return numerator/n;

}

DWORD WINAPI threadProc(LPVOID par)

{

int threadIndex = *((int *)par);

sums[threadIndex] = 0;

for(int i=threadIndex; i

sums[threadIndex] += getMember(i+1, x);

SetEvent(eventHandle[threadIndex]);

delete par;

return 0;

}

DWORD WINAPI masterThreadProc(LPVOID par)

{

for( int i=0; i

WaitForMultipleObjects(NUMTHREADS,eventHandle,TRUE,INFINITE); // busy wait until all threads are done with computation of partial sums

res = 0;

for(int i=0; i

res += sums[i];

return 0;

}

int _tmain(int argc, _TCHAR* argv[])

{ clock_t start, stop;

threadHandles = new HANDLE[NUMTHREADS + 1];

eventHandle = new HANDLE[NUMTHREADS + 1];

sums = new double[NUMTHREADS];

start = clock();

for(int i=0; i

{

int * threadIdPtr = new int;

*threadIdPtr = i;

threadHandles[i] = CreateThread(NULL, 0, threadProc, threadIdPtr, CREATE_SUSPENDED, NULL);

eventHandle[i] = CreateEvent(NULL,TRUE,FALSE,NULL);

}

threadHandles[NUMTHREADS] = CreateThread(NULL, 0, masterThreadProc, NULL, 0, NULL);

printf("Count of ln(1 + x) Mercator's series members is %d\n",SERIES_MEMBER_COUNT);

printf("Argument value of x is %f\n", (double)x);

WaitForMultipleObjects(NUMTHREADS+1,threadHandles,TRUE,INFINITE);

stop = clock();

for(int i=0; i

delete threadHandles;

delete eventHandle;

delete sums;

printf("Result is %10.8f\n", res);

printf("By function call ln(1 + %f) = %10.8f\n",x, log(1+x));

printf("The time of calculation was %f seconds\n",((double)(stop - start)/1000.0));

printf("Press any key ... ");

getch();

}

3是否可以对该并行化方案进行进一步的优化?如何优化?

应该优化优化*eventHandle;

SetEvent(eventHandle[threadIndex]);

eventHandle = new HANDLE[NUMTHREADS + 1];

4 实验总结

模块四:信号量实验

3 确定串行版本项目为启动项,编译执行。

4 确定并行版本项目为启动项,编译执行。

修正后项目的输出结果为:

简答与思考:

1 Serial.cpp与Threaded.cpp代码执行结果不一致的原因是什么?

在多线程中fd 和TotalWords 为共享变量,在并发执行的过程中会造成数据冲突。

2 如何修改Threaded.cpp代码?写出修改思路和关键代码。

#include "stdafx.h"

HANDLE semaphore1,semaphore2;

FILE *fd;

int TotalEvenWords = 0, TotalOddWords = 0, TotalWords = 0;

const int NUMTHREADS = 4;

int GetNextLine(FILE *f, char *Line)

{

if (fgets(Line, 132, f)==NULL) if (feof(f))return EOF; else return 1;

}

int GetWordAndLetterCount(char *Line)

{

int Word_Count = 0, Letter_Count = 0;

for (int i=0;i<132;i++)

{

if ((Line[i]!=' ')&&(Line[i]!=0)&&(Line[i]!='\n')) Letter_Count++;

else {

if(Letter_Count!=0){

if (Letter_Count % 2) {

TotalOddWords++;

Word_Count++;

Letter_Count = 0;

}

else {

TotalEvenWords++;

Word_Count++;

Letter_Count = 0;

}

}

if (Line[i]==0) break;

}

}

return (Word_Count);

}

DWORD WINAPI CountWords(LPVOID arg)

{

BOOL bDone = FALSE ;

char inLine[132];

while (!bDone)

{

WaitForSingleObject(semaphore1,INFINITE);

bDone = (GetNextLine(fd, inLine) == EOF);

ReleaseSemaphore(semaphore1,1,NULL);

if (!bDone){

WaitForSingleObject(semaphore2,INFINITE);

TotalWords += GetWordAndLetterCount(inLine) ;

ReleaseSemaphore(semaphore2,1,NULL);

}

}

return 0;

}

int main()

{

HANDLE hThread[NUMTHREADS];

semaphore1 = CreateSemaphore(NULL,1,1,NULL);

semaphore2 = CreateSemaphore(NULL,1,1,NULL);

fd = fopen("InFile1.txt", "r");

for (int i = 0; i < NUMTHREADS; i++)

hThread[i] = CreateThread(NULL,0,CountWords,NULL,0,NULL);

WaitForMultipleObjects(NUMTHREADS, hThread, TRUE, INFINITE);

fclose(fd);

printf("Total Words = %8d\n\n", TotalWords);

printf("Total Even Words = %7d\nTotal Odd Words = %7d\n", TotalEvenWords, TotalOddWords);

}

3 是否还有更优的修改方案?为什么?

优化这些

HANDLE semaphore1,semaphore2;

WaitForSingleObject(semaphore1,INFINITE);

ReleaseSemaphore(semaphore1,1,NULL);

WaitForSingleObject(semaphore2,INFINITE);

ReleaseSemaphore(semaphore2,1,NULL);

semaphore1 = CreateSemaphore(NULL,1,1,NULL);

semaphore2 = CreateSemaphore(NULL,1,1,NULL);

在代码调优上做处理

4 实验总结

相关主题