首页 > 其他 > 详细

Console I/O 加上CreateThread

时间:2015-07-27 14:59:56      阅读:138      评论:0      收藏:0      [点我收藏+]

技术分享

//Console I/O 加上CreateThread
/*Demonsttrates how to write a program that cna use
CreateThread instead of calling _beginthreadex.
This program does not need the multithread library.
This program could use ReadConsole and WriteConsole.
There are minor but significant differences between thest
functions and ReadFile and WriteFile
this program is ANSI only ,it will not compile for Unicode. 
*/
#define WIN32_LEAN_AND_MEAN
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>//to init rand()
#include "MtVerify.h"


/***************************/
/*Constants*/
#define MAX_THREADS 256
#define INPUT_BUF_SIZE 80
#define BANNER_SIZE 12
#define OUTPUT_TEXT_COLOR BACKGROUND_BLUE |\
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
/******************************
*Function Prototypes 
*/
void MainLoop(void);
void ClearScreen(void);
void ShutDownThreads(void);
void Prompt(LPCSTR str);//display title bar info
int StripCr(LPSTR buf);
/*Thread  startup function*/
DWORD WINAPI BannerProc(LPVOID pParam);
/*************************************
* Global Variables*/
HANDLE hConsoleIn;
HANDLE hCONSOLEOut;
HANDLE hRunObject;
HANDLE ThreadHandles[MAX_THREADS];
int nThreads;//number of threads started


CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
/******************************************
*Stucture passed to thread on startup */
typedef struct
{
TCHAR buf[INPUT_BUF_SIZE];
SHORT x;
SHORT y;
} DataBlock;


/***************************************************
primary thread enters here*/
int main()
{
/*Get display screen information &clear the screen*/
hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);
hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsoleOut, &csbiInfo);
ClearScreen();
/*Create the event object that keeps threads running*/
MTVERIFY(hRunObject = CreateEvent(NULL, TRUE, 0, NULL));
/*Start waiting for keyboard input to dispatch threads or exit*/
MainLoop();
ShutDownThreads();
ClearScreen();
CloseHandle(hRunObject);
CloseHandle(hConsoleIn);
CloseHandle(hConsoleOut);
return EXIT_SUCCESS;
}


void ShutDownThreads(void)
{
if (nThreads > 0)
{
/*since this is a manual event,all threads will be 
woken up at once*/
MTVERIFY(SetEvent(hRunObject));
MTVERIFY(WaitForMultipleObjects(nThreads,
ThreadHandles, TRUE, INFINITE) != WAIT_FAILED);
while (--nThreads)
{
MTVERIFY(CloseHandle(ThreadHandles[nThreads]));
}
}
}
/*dispatch and count threads*/
void MainLoop(void)
{
TCHAR buf[INPUT_BUF_SIZE];
DWORD bytesRead;
DataBlock *data_block;
DWORD thread_id;
srand(time(NULL));
for (;;)
{
Prompt("Type string to display or ENTER to exit:");
MTVERIFY(ReadFile(hConsoleIn, buf, INPUT_BUF_SIZE - 1,
&bytesRead, NULL));
/*ReadFile is binary,not line oriented,so terminate the string*/
buf[bytesRead] = ‘\0‘;
MTVERIFY(FlushConsoleInputBuffer(hConsoleIn));
if (StripCr(buf) == 0)
break;
if (nThreads < MAX_THREADS)
{
data_block = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DataBlock));
strcpy(data_block->buf, buf);
data_block->x = rand() *(csbiInfo.dwSize.X - BANNER_SIZE) / RAND_MAX;
data_block_->y = rand()*(csbiInfo.dwSize.Y - 1) / RAND_MAX + 1;
MTVERIFY(ThreadHandles[nThreads++] = CreateThread(
NULL, 0, BannerProc, data_block, 0, &thread_id));
}
}
}
void ClearScreen(void)
{
DWORD dummy;
COORD Home = { 0, 0 };
FillConsoleOutputAttribute(hConsoleOut,csbiInfo.wAttributes,
csbiInfo.dwSize.X*csbiInfo.dwSize.Y,Home,&dummy);
FillConsoleOutputCharacter(hCOnsoleOut, ‘ ‘,
csbiInfo.dwSize.X*csbiInfo.dwSize.Y, Home, &dummy);
}
void Prompt(LPCSTR str)
{
COORD Home = {0,0};
DWORD dummy;
int len = strlen(str);
SetConsoleCursorPosition(hCONSOLEOut, Home);
WriteFile(hConsoleOut, str, len, &dummy, FALSE);
Home.X = len;
FillConsoleOutputCharacter(hConsoleOut, ‘ ‘,
csbiInfo.dwSize.X - len, Home, &dummy);
}
/*********************************
 Routines from here down are used only by worker threads*/
DWORD WINAPI BannerProc(LPVOID pParam)
{
DataBlock *thread_data_block = pParam;
COORD TopLeft = { 0, 0 };
COORD Size = { BANNER_SIZE, 1 };
int i, j;
int len;
int ScrollPosition = 0;
TCHAR OutputBuf[INPUT_BUF_SIZE + BANNER_SIZE];
CHAR_INFO CharBuf[INPUT_BUF_SIZE + BANNER_SIZE];
SMALL_RECT rect;


rect.Left = thread_data_block->x;
rect.Right = rect.Left + BANNER_SIZE;
rect.Top = thread_data_block->y;
rect.Bottom = rect.Top;
strcpy(OutputBuf, thread_data_block->buf);
len = strlen(OutputBuf);
for (i = len; i < BANNER_SIZE; i++)
OutputBuf[i] = ‘ ‘;
if (len < BANNER_SIZE) len = BANNER_SIZE;
strncpy(OutputBuf + len, OutputBuf, BANNER_SIZE);
OutputBuf[len + BANNER_SIZE - 1] = ‘\0‘;
MTVERIFY(HeapFree(GetProcessHeap(), 0, pParam));
do
{
for (i = ScrollPosition++, j = 0; j < BANNER_SIZE; i++, j++)
{
CharBuf[j].Char.AsciiChar = OutputBuf[i];
CharBuf[j].Attributes = OUTPUT_TEXT_COLOR;
}
if (ScrollPosition == len)
ScrollPosition = 0;
MTVERIFY(WriteConsoleOutput(hConsoleOut, CharBuf, Size, TopLeft, &rect));
} while (WaitForSingleObject(hRunObject, 125L) == WAIT_TIMEOUT);
return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

Console I/O 加上CreateThread

原文:http://blog.csdn.net/wangfengfan1/article/details/47084305

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!