Solved

Independently running functions...

Posted on 2000-03-27
19
360 Views
Last Modified: 2010-04-15
Hi all!  I am wondering how I can write a function (or some other method) that will run independantly of the rest of my program.  For example, a clock that will constantly update itself, or a count-down timer that counts down while the user is doing something else, like trying to answer a question.  I would appreciate some help here, especially some code examples.

the_bikeman
0
Comment
Question by:the_bikeman
  • 7
  • 3
  • 3
  • +4
19 Comments
 
LVL 4

Expert Comment

by:feenix
Comment Utility
This can be accomplished with threads. What opertaing system are you using? If Windows, check out the cretethread function in your compiler's help file.
0
 
LVL 1

Expert Comment

by:bcoleman
Comment Utility
Need operating system(Windows/linux)?
0
 
LVL 1

Expert Comment

by:ntdragon
Comment Utility
try multi thread
#include <windows.h>
_beginthread(funcpointer,0,&ID);
it will run the funcpointer on another thread ndependantly of the rest of your program

if i didn't understand your prob right explaine it to me
0
 
LVL 1

Author Comment

by:the_bikeman
Comment Utility
I am running on the Windows OS, though my program is actually for DOS.  If someone has a solution for Windows but not DOS, I'll live with it, as the program probably will never be run in a DOS only environment anyway.

ntdragon:  could you give me an example of using
                  _beginthread()?

the_bikeman
0
 

Accepted Solution

by:
nisa earned 200 total points
Comment Utility
Hi,

   Below are the sample codes on using _beginthread(). In the example myTimer thread will concurrently run with its primary threads(the one that launch it) in the same address space.

The prototype:

unsigned long _beginthread( void( __cdecl *start_address )( void * ), unsigned stack_size, void *arglist );


Example:

#include <process.h>

/* timer routine */
void myTimer( void *dummy )
{
   while(1)
   {
     //do your timer stuff here
   }
}

void main()
{
/* Launch myTimer thread */
    _beginthread( myTimer, //you timer
                 0,    //stack size
                  NULL );//no arguement

    while(1)
    {
        //do something else
    }
}

Best Regards,

Nisa.
 
0
 
LVL 12

Expert Comment

by:pjknibbs
Comment Utility
A warning about threads: be *very* careful how you use them. For instance, if you don't use the proper synchronisation functions when accessing global data from your second thread, you could end up with all sorts of niggling bugs which will be near impossible to find.
0
 
LVL 1

Author Comment

by:the_bikeman
Comment Utility
Thanks, Nisa!  I'll try that, and if it works, I'll accept that as an answer.  I love this place, it gets some tough problems solved fairly quickly!

the_bikeman
0
 
LVL 2

Expert Comment

by:fremsley
Comment Utility
If you only want to perform very simple tasks like counting down in that DOS program you could link the routine into the timer interrupt. Your function will then be executed approx. 18 time per second.
0
 
LVL 1

Expert Comment

by:ntdragon
Comment Utility
ok i see you got an example allready but i"ll give another one


#pragma hdrstop
#include <condefs.h>


//---------------------------------------------------------------------------
#pragma argsused
/*  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.
 *
 *  This program requires the multithread library. For example, compile
 *  with the following command line:
 *      CL /MT BOUNCE.C
 */

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

#define MAX_THREADS  32

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

void main( void );                     /* Thread 1: main */
void KbdFunc( void  );                 /* Keyboard input, thread dispatch */
void BounceProc( void * MyID1 );        /* 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 */


void 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 );
}

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 *MyID1 )
{
    char *MyID=(char*)MyID1;
    char      MyCell, OldCell;
    WORD      MyAttrib, OldAttrib;
    char      BlankCell = 0x20;
    COORD     Coords, Delta;
    COORD     Old = {0,0};
    DWORD     Dummy;

/* Generate update increments and initial display coordinates. */
    srand( (unsigned) *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 )
{
    char    NThreadMsg[80];

    sprintf( NThreadMsg, "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 );
}


this is from msdn lib i compiled it in C++Builder

now a little bit about it
the _beginthread func will get a pointer to function and it runs it on another thread
the idea is that using it you can run a func indepandly to the rest of your prog
the func and your prog will run at the same time
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 1

Author Comment

by:the_bikeman
Comment Utility
Adjusted points from 100 to 200
0
 
LVL 1

Author Comment

by:the_bikeman
Comment Utility
When I posted the question I did not expect to receive such great feedback and answers.  Huge thanks to Nisa and NtDragon!!!

the_bikeman
0
 
LVL 1

Author Comment

by:the_bikeman
Comment Utility
Nisa:

I compiled your program exactly as you gave it to me, but I get a compiler error:  undefined reference to '_beginthread'

Could you help me out here?
0
 
LVL 1

Author Comment

by:the_bikeman
Comment Utility
Another note, I am using Gcc for DOS, and I don't have the windows.h library that NtDragon refered to.

the_bikeman
0
 
LVL 12

Expert Comment

by:pjknibbs
Comment Utility
Threads are only available when writing a Windows application (or a Windows console-mode application). If you're actually writing a 16-bit DOS application, you won't be able to use them.
0
 
LVL 1

Author Comment

by:the_bikeman
Comment Utility
Djgpp is a 32-bit development tool, not 16-bit.  And I am running under windows, so it really isn't a 16-bit application, is it?

the_bikeman
0
 
LVL 12

Expert Comment

by:pjknibbs
Comment Utility
Of course it is, if it's written as one. All those old 16-bit DOS programs which run fine on Win9x don't miraculously become 32-bit just because they're running under Windows. Bottom line: if the EXE file produced by your compiler will run in DOS mode (i.e. when Windows isn't running), it isn't a Win32 console application and won't be able to use threads.
0
 

Expert Comment

by:nisa
Comment Utility
Hi,
  You have to include:
#include <windows.h>
#include <winbase.h>

Also this program need to use a multithreaded library. If VC++ then u have to compile with /MT compiler switch. I never have experience with gcc compiler. Is there any documentation of the compiler that discuss about compiling with multithreaded library?. A decent "modern" C/C++ compiler should have support a multithreaded library.


Best Regards,


Nisa.

 
0
 
LVL 1

Expert Comment

by:ntdragon
Comment Utility
first the windows.h header you can get from the net if you don't have it

second i got this error when i tried to compile it in vc so i tried C++Builder and it worked fine there

so if you can compile it in your gcc compiler try another one
<if you can try C++Builder i mean borland compiler>
0
 
LVL 2

Expert Comment

by:fremsley
Comment Utility
the_bikeman> Djgpp is a 32-bit development tool, not 16-bit.
the_bikeman> And I am running under windows, so it really isn't a
the_bikeman> 16-bit application, is it?

pjknibbs> Of course it is, if it's written as one.
pjknibbs> All those old 16-bit DOS programs which run fine on Win9x
pjknibbs> don't miraculously become 32-bit just because they're
pjknibbs> running under Windows.

If you are using djgpp the programs _are_ 32-bit, however they can not access the Win32 API -- and thus can not use Windows threads. There seems however to be an implementation of the POSIX thread library for djgpp available at:

  ftp://ftp.cs.fsu.edu/pub/PART/PTHREADS/pthreads.zip

regards
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now