码迷,mamicode.com
首页 > 其他好文 > 详细

Console I/O 加上CreateThread

时间:2015-07-27 15:02:42      阅读:127      评论: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
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!