Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Independently running functions...

Posted on 2000-03-27
19
Medium Priority
?
369 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 3
  • 3
  • +4
19 Comments
 
LVL 4

Expert Comment

by:feenix
ID: 2661077
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
ID: 2661177
Need operating system(Windows/linux)?
0
 
LVL 1

Expert Comment

by:ntdragon
ID: 2661650
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 does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 1

Author Comment

by:the_bikeman
ID: 2662292
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 800 total points
ID: 2662741
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
ID: 2663194
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
ID: 2663227
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
ID: 2663417
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
ID: 2665604
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
 
LVL 1

Author Comment

by:the_bikeman
ID: 2665721
Adjusted points from 100 to 200
0
 
LVL 1

Author Comment

by:the_bikeman
ID: 2665729
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
ID: 2668001
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
ID: 2668020
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
ID: 2668155
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
ID: 2668222
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
ID: 2668302
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
ID: 2668625
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
ID: 2668737
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
ID: 2668821
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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
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.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

705 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