| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 447 人关注过本帖, 1 人收藏
标题:多线程入门时遇到了一个问题
只看楼主 加入收藏
thlgood
Rank: 5Rank: 5
等 级:职业侠客
帖 子:281
专家分:381
注 册:2010-9-24
结帖率:91.43%
收藏(1)
 问题点数:0 回复次数:3 
多线程入门时遇到了一个问题
程序代码:
/*我在网上下载了一段关于多线程的代码,有几个地方我不是很懂,
疑问一:为何函数声明里面,连main都要声明。
疑问二:为何会提示_beginthread和sprintf_s这两个函数没哟声明
_beginthread不是在process.h头文件中已经声明了吗?
*/
// sample_multithread_c_program.c
// compile with: /c
//
//  Bounce - Creates a new thread each time the letter 'a' is typed.
//  Each thread bounces a happy face of a different color around
//  the screen. All threads are terminated when the letter 'Q' is
//  entered.
//

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <process.h>

#define MAX_THREADS  32

// The function getrandom returns a random number between 
// min and max, which must be in integer range.
#define getrandom( min, max ) (SHORT)((rand() % (int)(((max) + 1) - \
                               (min))) + (min))

int main( void );                    // Thread 1: main 
void KbdFunc( void  );               // Keyboard input, thread dispatch
void BounceProc( void * MyID );      // Threads 2 to n: display 
void ClearScreen( void );            // Screen clear 
void ShutDown( void );               // Program shutdown 
void WriteTitle( int ThreadNum );    // Display title bar information 

HANDLE  hConsoleOut;                 // Handle to the console 
HANDLE  hRunMutex;                   // "Keep Running" mutex 
HANDLE  hScreenMutex;                // "Screen update" mutex
int     ThreadNr;                    // Number of threads started 
CONSOLE_SCREEN_BUFFER_INFO csbiInfo; // Console information 


int main() // Thread One 
{
    // Get display screen information & clear the screen.
    hConsoleOut = GetStdHandle( STD_OUTPUT_HANDLE );
    GetConsoleScreenBufferInfo( hConsoleOut, &csbiInfo );
    ClearScreen();
    WriteTitle( 0 );

    // Create the mutexes and reset thread count.
    hScreenMutex = CreateMutex( NULL, FALSE, NULL );  // Cleared 
    hRunMutex = CreateMutex( NULL, TRUE, NULL );      // Set 
    ThreadNr = 0;

    // Start waiting for keyboard input to dispatch threads or exit.
    KbdFunc();

    // All threads done. Clean up handles.
    CloseHandle( hScreenMutex );
    CloseHandle( hRunMutex );
    CloseHandle( hConsoleOut );
    return 0;
}

void ShutDown( void ) // Shut down threads 
{
    while ( ThreadNr > 0 )
    {
        // Tell thread to die and record its death.
        ReleaseMutex( hRunMutex );
        ThreadNr--;   
    }
    
    // Clean up display when done
    WaitForSingleObject( hScreenMutex, INFINITE );
    ClearScreen();
}

void KbdFunc( void ) // Dispatch and count threads.
{
    int         KeyInfo;

    do
    {
        KeyInfo = _getch();
        if ( tolower( KeyInfo ) == 'a' && 
             ThreadNr < MAX_THREADS )
        {
            ThreadNr++;
            _beginthread( BounceProc, 0, &ThreadNr );
            WriteTitle( ThreadNr );
        }
    } while( tolower( KeyInfo ) != 'q' );

    ShutDown();
}

void BounceProc( void *pMyID )
{
    char    MyCell, OldCell;
    WORD    MyAttrib, OldAttrib;
    char    BlankCell = 0x20;
    COORD   Coords, Delta;
    COORD   Old = {0,0};
    DWORD   Dummy;
    char    *MyID = (char*)pMyID;

    // Generate update increments and initial 
    // display coordinates.
    srand( (unsigned int) *MyID * 3 );

    Coords.X = getrandom( 0, csbiInfo.dwSize.X - 1 );
    Coords.Y = getrandom( 0, csbiInfo.dwSize.Y - 1 );
    Delta.X = getrandom( -3, 3 );
    Delta.Y = getrandom( -3, 3 );

    // Set up "happy face" & generate color 
    // attribute from thread number.
    if( *MyID > 16)
        MyCell = 0x01;          // outline face 
    else
        MyCell = 0x02;          // solid face 
    MyAttrib =  *MyID & 0x0F;   // force black background 

    do
    {
        // Wait for display to be available, then lock it.
        WaitForSingleObject( hScreenMutex, INFINITE );

        // If we still occupy the old screen position, blank it out. 
        ReadConsoleOutputCharacter( hConsoleOut, &OldCell, 1, 
                                    Old, &Dummy );
        ReadConsoleOutputAttribute( hConsoleOut, &OldAttrib, 1, 
                                    Old, &Dummy );
        if (( OldCell == MyCell ) && (OldAttrib == MyAttrib))
            WriteConsoleOutputCharacter( hConsoleOut, &BlankCell, 1,
                                         Old, &Dummy );

        // Draw new face, then clear screen lock 
        WriteConsoleOutputCharacter( hConsoleOut, &MyCell, 1, 
                                     Coords, &Dummy );
        WriteConsoleOutputAttribute( hConsoleOut, &MyAttrib, 1, 
                                     Coords, &Dummy );
        ReleaseMutex( hScreenMutex );

        // Increment the coordinates for next placement of the block. 
        Old.X = Coords.X;
        Old.Y = Coords.Y;
        Coords.X += Delta.X;
        Coords.Y += Delta.Y;

        // If we are about to go off the screen, reverse direction 
        if( Coords.X < 0 || Coords.X >= csbiInfo.dwSize.X )
        {
            Delta.X = -Delta.X;
            Beep( 400, 50 );
        }
        if( Coords.Y < 0 || Coords.Y > csbiInfo.dwSize.Y )
        {
            Delta.Y = -Delta.Y;
            Beep( 600, 50 );
        }
    }
    // Repeat while RunMutex is still taken. 
    while ( WaitForSingleObject( hRunMutex, 75L ) == WAIT_TIMEOUT );
}

void WriteTitle( int ThreadNum )
{
    enum { 
        sizeOfNThreadMsg = 80 
    };
    char    NThreadMsg[sizeOfNThreadMsg];

    sprintf_s( NThreadMsg, sizeOfNThreadMsg, 
               "Threads running: %02d.  Press 'A' "
               "to start a thread,'Q' to quit.", ThreadNum );
    SetConsoleTitle( NThreadMsg );
}

void ClearScreen( void )
{
    DWORD    dummy;
    COORD    Home = { 0, 0 };
    FillConsoleOutputCharacter( hConsoleOut, ' ', 
                                csbiInfo.dwSize.X * csbiInfo.dwSize.Y, 
                                Home, &dummy );
}
搜索更多相关主题的帖子: 多线程 
2011-04-17 09:22
flylee
Rank: 5Rank: 5
等 级:职业侠客
帖 子:309
专家分:374
注 册:2004-8-10
收藏
得分:0 
声不声明main就一个习惯问题吧
从代码看_beginthread和sprintf_s应该是库里提供的,_beginthread创建线程,sprintf_s应该和sprintf差不多吧

我做的多线程都是unix下的,对windows这块没接触过,不喜欢微软的这些设计
2011-04-17 09:51
thlgood
Rank: 5Rank: 5
等 级:职业侠客
帖 子:281
专家分:381
注 册:2010-9-24
收藏
得分:0 
期待大大们发力……

o(∩∩)Linux & Python 群:187367181
2011-04-17 19:05
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
不知道楼主所谓的入门其实有什么样的基础水平。

不过我也不是很懂 windows 的那套东西。我有一个同学学这个,我跟着也看了一点,皮毛而已。
2011-04-18 00:36
快速回复:多线程入门时遇到了一个问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.035835 second(s), 8 queries.
Copyright©2004-2025, BCCN.NET, All Rights Reserved