Board index » delphi » Can I run two procedures simultaneously?

Can I run two procedures simultaneously?

Hi,

I'm pretty new to programming and though I have played with TP7 a
little, I'm still learning, so please excuse me if this is a dumb
question. The subject line pretty much conveys my problem... For
example, can I have user input, the cursor blinking and all, and at
the same time have some text scrolling by at the bottom of the screen?

Instead of waiting for one procedure to finish and going to a 2nd one
while the 1st one is sitting there and doing nothing, I'd like to have
both running at the same time.

I think this is called multi-threading in Windows, but I have no idea
how to implement it in pascal. I'm using TP 7 in dos and 1.5 in Win98.

Thanks in advance.

 

Re:Can I run two procedures simultaneously?


jacob [mailto:removeme.shad...@erols.com] decided to regale us with

Quote
>Instead of waiting for one procedure to finish and going to a 2nd one
>while the 1st one is sitting there and doing nothing, I'd like to have
>both running at the same time.

>I think this is called multi-threading in Windows, but I have no idea
>how to implement it in pascal. I'm using TP 7 in dos and 1.5 in Win98.

There are a number of multi-tasking units around that are either pseudo
(programmer has to explicitly call a procedure) or true (works without
programmer calling a procedure). Pseudo multitasking is far easier to
implement.

SWAG has some units http://www.gdsoft.com/swag/
Try Fanz Glaser at http://www.geocities.com/SiliconValley/2926/tp.html
Also a pseudo multitasking unit via http://www.pedt.demon.co.uk/

--
Pedt

Re:Can I run two procedures simultaneously?


Quote
In article <36a183e8.39399...@news.erols.com> removeme.shad...@erols.com wrote...
> I think this is called multi-threading in Windows, but I have no idea
> how to implement it in pascal. I'm using TP 7 in dos and 1.5 in Win98.

No, this isn't multithreading, but you can do it by having the 'user
input' routine(s) check something like this;

        if Keypressed
           then Deal_With_User_Input
           else Scroll-Text

A better solution would probably to use a toolkit like Object
Professional or Technojocks Object Toolkit, where a 'keypressed' routine
(which hooks into all other I/O functions) can be assigned an idle hook.
This is a user-defined procedure which is called when ever you are (1)
polling the keyboard and (2) there is no key pressed at that time.

Mike{*word*106}son, Black Cat Software Factory, Edinburgh, Scotland
fax 0131-271-1551 - Columnated Ruins Domino - Mellotron M400 #996

Re:Can I run two procedures simultaneously?


Quote
jacob wrote:
> I'm pretty new to programming and though I have played with TP7 a
> little, I'm still learning, so please excuse me if this is a dumb
> question. The subject line pretty much conveys my problem... For
> example, can I have user input, the cursor blinking and all, and at
> the same time have some text scrolling by at the bottom of the screen?

> Instead of waiting for one procedure to finish and going to a 2nd one
> while the 1st one is sitting there and doing nothing, I'd like to have
> both running at the same time.

> I think this is called multi-threading in Windows, but I have no idea
> how to implement it in pascal. I'm using TP 7 in dos and 1.5 in Win98.

Have you programmed in another language than TP before? If you are
generally new to programming, the following might maybe not yet be very
clear to you. Sorry in this case.

It is possible by using an interrupt procedure that hooks interrupt 1Ch.
Such an interrupt procedure will be called around 18.2 times per second,
in the average. Therefore, while a procedure is being executed, the
interrupt procedure will be called several times:

procedure 1 being executed
interrupt procedure being called, executed, and terminated
procedure 1 being continued
interrupt procedure being called, executed, and terminated
...

and this happens approximately 18.2 times a second.

I suggest you consider the following program. What it does is simply
calculating the amount of time you need to input your name.
Note that there are of course much better and faster ways to measure
time, but it is simply to demonstrate the use of an interrupt procedure
here.

uses crt, dos;
var
  YourName  : string;
  OldVector : pointer;
  Calls : word;

procedure MeasureTime; interrupt;
begin
  calls := calls + 1;

  { The following simply writes the number of times the interrupt
    procedure was called directly to video memory, to prevent the cursor
    from jumping around and messing up the screen. }
  Mem[$B800:152] := (calls div 100) + 48;
  Mem[$B800:154] := (calls mod 100 div 10)+ 48;
  Mem[$B800:156] := (calls mod 10) + 48
end;

procedure Enter_Your_Name;
begin
  write('Enter your name: ');
  readln(YourName)
end;

begin
  clrscr;
  GetIntVec($1C, OldVector);
  SetIntVec($1C, Addr(MeasureTime));

  Enter_Your_Name;
  SetIntVec($1C, OldVector);

  writeln('You took ', calls / 18.2:2:2, ' sec. to enter your name');
  repeat until readkey <> ''
end.

Re:Can I run two procedures simultaneously?


Quote
On Sun, 17 Jan 1999 12:06:46 +0100, Frederic <f...@rz-online.de> wrote:
>jacob wrote:

>> I'm pretty new to programming and though I have played with TP7 a
>> little, I'm still learning, so please excuse me if this is a dumb
>> question. The subject line pretty much conveys my problem... For
>> example, can I have user input, the cursor blinking and all, and at
>> the same time have some text scrolling by at the bottom of the screen?

>> Instead of waiting for one procedure to finish and going to a 2nd one
>> while the 1st one is sitting there and doing nothing, I'd like to have
>> both running at the same time.

>> I think this is called multi-threading in Windows, but I have no idea
>> how to implement it in pascal. I'm using TP 7 in dos and 1.5 in Win98.

>Have you programmed in another language than TP before? If you are
>generally new to programming, the following might maybe not yet be very
>clear to you. Sorry in this case.

>It is possible by using an interrupt procedure that hooks interrupt 1Ch.
>Such an interrupt procedure will be called around 18.2 times per second,
>in the average. Therefore, while a procedure is being executed, the
>interrupt procedure will be called several times:

>procedure 1 being executed
>interrupt procedure being called, executed, and terminated
>procedure 1 being continued
>interrupt procedure being called, executed, and terminated
>...

>and this happens approximately 18.2 times a second.

>I suggest you consider the following program. What it does is simply
>calculating the amount of time you need to input your name.
>Note that there are of course much better and faster ways to measure
>time, but it is simply to demonstrate the use of an interrupt procedure
>here.

>uses crt, dos;
>var
>  YourName  : string;
>  OldVector : pointer;
>  Calls : word;

>procedure MeasureTime; interrupt;
>begin
>  calls := calls + 1;

>  { The following simply writes the number of times the interrupt
>    procedure was called directly to video memory, to prevent the cursor
>    from jumping around and messing up the screen. }
>  Mem[$B800:152] := (calls div 100) + 48;
>  Mem[$B800:154] := (calls mod 100 div 10)+ 48;
>  Mem[$B800:156] := (calls mod 10) + 48
>end;

>procedure Enter_Your_Name;
>begin
>  write('Enter your name: ');
>  readln(YourName)
>end;

>begin
>  clrscr;
>  GetIntVec($1C, OldVector);
>  SetIntVec($1C, Addr(MeasureTime));

>  Enter_Your_Name;
>  SetIntVec($1C, OldVector);

>  writeln('You took ', calls / 18.2:2:2, ' sec. to enter your name');
>  repeat until readkey <> ''
>end.

This is pretty cool; thanks. Unfortunatly, I'm not too clear as to
what the lines GetIntVec and SetIntVec do. I've looked in the help of
TP 7, but I'm afraid its just over my head for now. Can you recommend
a good book or perhaps an internet site explaining this stuff?

Re:Can I run two procedures simultaneously?


jacob schrieb:

Quote
> This is pretty cool; thanks. Unfortunatly, I'm not too clear as to
> what the lines GetIntVec and SetIntVec do. I've looked in the help of
> TP 7, but I'm afraid its just over my head for now. Can you recommend
> a good book or perhaps an internet site explaining this stuff?

Every good book about Pascal should deal with interrupts. Here is a short
explanation:

A software interrupt routine is a routine provided by DOS, for example. It is
called via a special machine language instruction, INT xx. xx is the number
of the interrupt to be called; it can range from 0 to 255. So a normal system
disposes of 256 interrupts. Using such interrupts, programs can display a
string on the screen, read from a file, and so on. They just call the
appropriate interrupt, tell it what exactly to do by passing a certain value
to the interrupt routine, and the interrupt routine does the rest. The
address in memory where a specific interrupt routine code is located is to be
found in the so-called "interrupt vectors".

There is one interrupt, number 28 (1Ch), which is called approximately 18.2
times a second. If I am right, it does not do anything - it just returns to
the point from where it was originally called.

You can "hook" an interrupt. This means that you write a procedure, and tell
the computer that from now on, whenever the interrupt occurs, this procedure
is called and executed. This is done using SetIntVec.

SetIntVec($1C, Addr(Your_Procedure)) sets the interrupt vector of interrupt
1Ch to the address of your procedure. From now on, whenever interrupt 1Ch is
called, your procedure is executed. Since interrupt 1Ch is called 18.2 times
a second, your procedure will from now on also be called 18.2 times a second.

Now, what, when your program is terminating. You don't need the interrupt
procedure anymore, and you want to restore the old state of the system.
Exactly - you have fortunately saved the address of the original vector in a
pointer, and you can now restore it using that pointer. A short skeleton for
a program using an interrupt procedure:

var
  OldVector : pointer;

procedure MyRoutine; interrupt;
begin
  ...
  ...
end;

begin
  GetIntVec($1C, OldVector);  { Save the old vector }
  SetIntVec($1C, Addr(MyRoutine));  { Install your own routine }

  { Your regular program }

  SetIntVec($1C, OldVector)  { Restore the old vector }
end;

Be wary of not making the interrupt routine last longer than 1 / 18.2 second.
Otherwise your computer may start behaving strangely.

I hope this helps you to get started. Later you will see that it is not this
simple anymore. You will have to call the old interrupt routine immediately
after yours, take care of which interrupts you can (not) call from within
another interrupt routine, and so on. But don't let this bother you now.

Re:Can I run two procedures simultaneously?


Quote
> Be wary of not making the interrupt routine last longer than 1 / 18.2 second.
> Otherwise your computer may start behaving strangely.

but it is possible to add some kind of variable from which to determine (sp?) if
procedure is still running and dont start it once again.

--
Ze{*word*104} [E-MAIL: cy...@vil.ktu.lt] [HP: not-yet]
?????????????????? ICQ: 14187537
??????? If Time Is Killing You - Kill Some For Time
?

Re:Can I run two procedures simultaneously?


Algirdas Kepezinskas schrieb:

Quote
> > Be wary of not making the interrupt routine last longer than 1 / 18.2 second.
> > Otherwise your computer may start behaving strangely.

> but it is possible to add some kind of variable from which to determine (sp?) if
> procedure is still running and dont start it once again.

How would you implement this? An interrupt procedure hooking 1Ch is necessarily and
irrevocably called 18.2 times a second by the system. There is no (simple) way to
alter this behavior.

If you mean the stack pointer with sp: it is not really a good idea. You cannot
foresee the value of the stack pointer when writing your program.
Maybe one could indeed add a boolean variable indicating whether the procedure is
still running. But no simple solution comes to my mind. Those I can think about
require too much code, and thus waste precious time. Fast processors are anyway
capable of executing several thousands (millions?) of instructions in 1 / 18.2
seconds. An interrupt routine is designed to execute a specific task, and if really
it takes unacceptably long to execute, then it is just badly written. Interrupt 1Ch
should anyway not be used for lengthy routines. It is better to hook another
interrupt which is called only on demand, and not at regular intervals.

Re:Can I run two procedures simultaneously?


no, you didnt get me right. I mean it is possible, once a procedure is started (lets say we know it _will_ last longer then 1/18.2
second), to set lets say runnign bollean to true, and on the start of procedure we do check:

if not runnging then
??? begin
??????? running:=1=1; (* i like this way of setting a boolean:)*);
??????? ,
??????? ,
??????? ,
??????? running:=1=0;
??? end;

this way, procedure wont be called until it will finish. It is tested:)

Quote
> > > Be wary of not making the interrupt routine last longer than 1 / 18.2 second.
> > > Otherwise your computer may start behaving strangely.

> > but it is possible to add some kind of variable from which to determine (sp?) if
> > procedure is still running and dont start it once again.

> How would you implement this? An interrupt procedure hooking 1Ch is necessarily and
> irrevocably called 18.2 times a second by the system. There is no (simple) way to
> alter this behavior.

> If you mean the stack pointer with sp: it is not really a good idea. You cannot
> foresee the value of the stack pointer when writing your program.
> Maybe one could indeed add a boolean variable indicating whether the procedure is
> still running. But no simple solution comes to my mind. Those I can think about
> require too much code, and thus waste precious time. Fast processors are anyway
> capable of executing several thousands (millions?) of instructions in 1 / 18.2
> seconds. An interrupt routine is designed to execute a specific task, and if really
> it takes unacceptably long to execute, then it is just badly written. Interrupt 1Ch
> should anyway not be used for lengthy routines. It is better to hook another
> interrupt which is called only on demand, and not at regular intervals.

--
Ze{*word*104} [E-MAIL: cy...@vil.ktu.lt] [HP: not-yet]
?????????????????? ICQ: 14187537
??????? If Time Is Killing You - Kill Some For Time
?

Other Threads