Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 373
  • Last Modified:

Independently running functions...

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
the_bikeman
Asked:
the_bikeman
  • 7
  • 3
  • 3
  • +4
1 Solution
 
feenixCommented:
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
 
bcolemanCommented:
Need operating system(Windows/linux)?
0
 
ntdragonCommented:
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
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
the_bikemanAuthor Commented:
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
 
nisaCommented:
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
 
pjknibbsCommented:
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
 
the_bikemanAuthor Commented:
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
 
fremsleyCommented:
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
 
ntdragonCommented:
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
 
the_bikemanAuthor Commented:
Adjusted points from 100 to 200
0
 
the_bikemanAuthor Commented:
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
 
the_bikemanAuthor Commented:
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
 
the_bikemanAuthor Commented:
Another note, I am using Gcc for DOS, and I don't have the windows.h library that NtDragon refered to.

the_bikeman
0
 
pjknibbsCommented:
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
 
the_bikemanAuthor Commented:
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
 
pjknibbsCommented:
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
 
nisaCommented:
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
 
ntdragonCommented:
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
 
fremsleyCommented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

  • 7
  • 3
  • 3
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now