Re: threads
yes , i`m using VC++ as compiler and this`s the all code :
/***
ThreadSync1.c
***/
#include <stdio.h>
#include <conio.h>
#include <process.h>
#include <windows.h>
#pragma pack(1)
/*================== Constants =================================*/
#define BUFFER_SIZE (64*1023)
#define NUM_OF_FUNCTIONS 2
#define THREAD_TOTAL_LIMIT 5
/*================= Data Types =================================*/
typedef struct _THREAD_PARAMETERS_
{
char *szFileName;
unsigned int uResult;
} THREAD_PARAMETERS;
typedef struct _THREAD_INFO_
{
DWORD dwThreadID;
void* pParam;
unsigned int uFunction;
} THREAD_INFO;
typedef struct _THREAD_FUNCTIONS_
{
DWORD(WINAPI *pThreadFunction[NUM_OF_FUNCTIONS])(void*);
void(*pPrintFunction[NUM_OF_FUNCTIONS])(THREAD_INFO*);
void*(*pInitParamFunction[NUM_OF_FUNCTIONS])(void);
char* cpMenuItems[NUM_OF_FUNCTIONS];
unsigned int uNumOfThreads[NUM_OF_FUNCTIONS];
unsigned int uThreadLimit[NUM_OF_FUNCTIONS];
unsigned int uTotalThreads;
THREAD_INFO* spThreadData[THREAD_TOTAL_LIMIT];
HANDLE hpThreads[THREAD_TOTAL_LIMIT];
} THREAD_FUNCTIONS;
/*================== Function prototypes =======================*/
DWORD WINAPI CountVowels (void* pParam);
void PrintNumOfVowels(void* pParam);
void* InitCountVowels(void);
DWORD WINAPI CountWords(void* pParam);
void PrintNumOfWords(void* pParam);
void* InitCountWords(void);
/*================== Functions =================================*/
void InitializeThreadFunctions(THREAD_FUNCTIONS* spTF)
{
memset(spTF, 0, sizeof(THREAD_FUNCTIONS));
spTF->uTotalThreads = 0;
spTF->cpMenuItems[0] = "Count the number of vowels in a text.";
spTF->pThreadFunction[0] = CountVowels;
spTF->pPrintFunction[0] = PrintNumOfVowels;
spTF->pInitParamFunction[0] = InitCountVowels;
spTF->uNumOfThreads[0] = 0;
spTF->uThreadLimit[0] = 3;
spTF->cpMenuItems[1] = "Count the number of words in a text.";
spTF->pThreadFunction[1] = CountWords;
spTF->pPrintFunction[1] = PrintNumOfWords;
spTF->pInitParamFunction[1] = InitCountWords;
spTF->uNumOfThreads[1] = 0;
spTF->uThreadLimit[1] = 3;
} /* InitializeThreadFunctions() */
/*--------------------------------------------------------------*/
void* InitCountVowels(void)
{
THREAD_PARAMETERS *spParam;
spParam = (THREAD_PARAMETERS*)malloc(sizeof(THREAD_PARAMETERS));
if (spParam != NULL)
{
spParam->szFileName = "file1.txt";
spParam->uResult = 0;
}
return spParam;
} /* InitCountVowels() */
/*--------------------------------------------------------------*/
DWORD WINAPI CountVowels (void* pParam)
{ /* Counts the number of vowels in a text. */
size_t i;
FILE *fp;
char *szText;
THREAD_PARAMETERS *spData = (THREAD_PARAMETERS*)pParam;
spData->uResult = 0;
szText = malloc(BUFFER_SIZE * sizeof(*szText));
if (szText != NULL)
{
fp = fopen(spData->szFileName, "rb");
if (fp != NULL)
{
Sleep(3000);
i = fread(szText, sizeof(*szText), BUFFER_SIZE, fp);
fclose(fp);
while (i != 0)
{
switch (toupper(szText[i]))
{
case 'A': case 'O': case 'U':
case 'E': case 'I': case 'Y':
spData->uResult++;
}
i--;
}
} // if (fp != NULL)
free(szText);
} // if (cpText != NULL)
return 0;
} /* CountVowels() */
/*--------------------------------------------------------------*/
void PrintNumOfVowels(THREAD_INFO* spThread)
{
THREAD_PARAMETERS* spParam = (THREAD_PARAMETERS*)(spThread->pParam);
printf("Thread function %u (TID = 0x%X) completed. There are %u vowels in the text.\n",
spThread->uFunction+1, spThread->dwThreadID,
spParam->uResult);
} /* PrintNumOfVowels() */
/*--------------------------------------------------------------*/
void* InitCountWords(void)
{
THREAD_PARAMETERS *spParam;
spParam = (THREAD_PARAMETERS*)malloc(sizeof(THREAD_PARAMETERS));
if (spParam != NULL)
{
spParam->szFileName = "file2.txt";
spParam->uResult = 0;
}
return spParam;
} /* InitCountWords() */
/*--------------------------------------------------------------*/
DWORD WINAPI CountWords(void* pParam)
{/* Counts the number of words in a text. */
size_t i;
FILE *fp;
char *szText;
THREAD_PARAMETERS *spData = (THREAD_PARAMETERS*)pParam;
spData->uResult = 0;
szText = malloc(BUFFER_SIZE * sizeof(*szText));
if (szText != NULL)
{
fp = fopen(spData->szFileName, "rb");
if (fp != NULL)
{
Sleep(4000);
i = fread(szText, sizeof(*szText), BUFFER_SIZE, fp);
fclose(fp);
while (i != 0)
{
while (i != 0 && szText[i] == ' ') i--;
if (i != 0) spData->uResult++;
while (i != 0 && szText[i] != ' ') i--;
}
} // if (fp != NULL)
free(szText);
} // if (cpText != NULL)
return 0;
} /* CountWords() */
/*--------------------------------------------------------------*/
void PrintNumOfWords(THREAD_INFO* spThread)
{
THREAD_PARAMETERS* spParam = (THREAD_PARAMETERS*)(spThread->pParam);
printf("Thread function %u (TID = 0x%X) completed. There are %u words in the text.\n",
spThread->uFunction+1, spThread->dwThreadID,
spParam->uResult);
} /* PrintNumOfWords() */
/*--------------------------------------------------------------*/
THREAD_INFO* StartNewThread(THREAD_FUNCTIONS* spTF, unsigned int uFunction)
{
THREAD_INFO *spNewThread = NULL;
if (uFunction < NUM_OF_FUNCTIONS)
{
if ( (spTF->uNumOfThreads[uFunction] < spTF->uThreadLimit[uFunction]) &&
(spTF->uTotalThreads < THREAD_TOTAL_LIMIT) )
{
spNewThread = (THREAD_INFO*)malloc(sizeof(THREAD_INFO));
if (spNewThread != NULL)
{
spTF->spThreadData[spTF->uTotalThreads] = spNewThread;
spNewThread->uFunction = uFunction;
spNewThread->pParam = spTF->pInitParamFunction[uFunction]();
spTF->hpThreads[spTF->uTotalThreads] = (HANDLE)_beginthreadex(NULL, 0,
spTF->pThreadFunction[uFunction],
spNewThread->pParam, 0,
&(spNewThread->dwThreadID));
spTF->uTotalThreads++;
spTF->uNumOfThreads[uFunction]++;
} /* if (spNewThread != NULL) */
}
} /* if (uFunction < NUM_OF_FUNCTIONS) */
return spNewThread;
} /* StartNewThread() */
/*--------------------------------------------------------------*/
void PrintResults(THREAD_FUNCTIONS* spTF)
{
int i, j;
DWORD dwExitCode;
THREAD_INFO** spThreads = spTF->spThreadData;
i = spTF->uTotalThreads - 1;
while (i >= 0)
{
GetExitCodeThread(spTF->hpThreads[i], &dwExitCode);
if (dwExitCode != STILL_ACTIVE)
{
printf(" PrintResults(): i=%d, uTotalThreads=%d.\n", i, spTF->uTotalThreads);
spTF->pPrintFunction[spThreads[i]->uFunction](spThreads[i]);
free(spThreads[i]->pParam);
spThreads[i]->pParam = NULL;
spTF->uTotalThreads--;
spTF->uNumOfThreads[spThreads[i]->uFunction]--;
free(spThreads[i]);
spThreads[i] = NULL;
CloseHandle(spTF->hpThreads[i]);
for (j = i; j < (int)spTF->uTotalThreads; j++)
{
printf(" PrintResults(): j=%d, uTotalThreads=%d.\n", j, spTF->uTotalThreads);
spThreads[j] = spThreads[j+1];
spTF->hpThreads[j] = spTF->hpThreads[j+1];
}
spThreads[spTF->uTotalThreads] = NULL;
spTF->hpThreads[spTF->uTotalThreads] = NULL;
} /* if (dwExitCode != STILL_ACTIVE) */
i--;
} /* for (i) */
} /* PrintResults() */
/*--------------------------------------------------------------*/
void DisplayMainMenu(const char** cpMenuItems,
unsigned int uNumOfFunctions)
{
unsigned int i;
printf("Choose one of the following actions:\n");
for (i = 0; i < uNumOfFunctions; i++)
printf(" %u - %s\n", i+1, cpMenuItems[i]);
printf(" q - Exit.\n");
} /* DisplayMainMenu() */
/*--------------------------------------------------------------*/
void main()
{
int nKey = 0; /* character entered from keyboard */
THREAD_FUNCTIONS sTF;
THREAD_INFO* spThread;
DWORD dwResult;
DWORD dwTimeout = 10;
BOOL bQuit;
InitializeThreadFunctions(&sTF);
DisplayMainMenu(sTF.cpMenuItems, NUM_OF_FUNCTIONS);
do
{
if ( _kbhit() ) /* if a key has been pressed */
{
nKey = _getch(); /* read the key code */
if (nKey >= '1' && nKey <= '2')
{
spThread = StartNewThread(&sTF, nKey-'1');
if (spThread != NULL)
printf("Started thread function %u (TID = 0x%X).\n",
spThread->uFunction+1, spThread->dwThreadID);
else
printf("Error: thread function %u cannot be started.\n", nKey-'0');
}
} /* if ( _kbhit() ) */
bQuit = ((nKey == 'q') || (nKey == 'Q'));
if (bQuit)
dwTimeout = INFINITE;
dwResult = WaitForMultipleObjects(sTF.uTotalThreads, sTF.hpThreads, bQuit, dwTimeout);
if ( (dwResult != WAIT_FAILED) && (dwResult != WAIT_TIMEOUT) )
{
printf("---main(): bQuit=%d, dwTimeout=%d, dwResult=%d, uTotalThreads=%d.\n",
bQuit, dwTimeout, dwResult, sTF.uTotalThreads);
PrintResults(&sTF);
}
Sleep(10);
} while (!bQuit);
printf("\nAll threads terminated.\n");
} /* main() */
Last edited by admin : 03-Jun-2009 at 03:00.
Reason: Please insert your example C/C++ codes between [CPP] and [/CPP] tags
|