Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2002-01

two questions plz help

20 messages · 9 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Unknown author

Hello fpc-pascal,

i have two questions :

1. how i can write multithreaded program in free pascal ( using linux unit and clone function ??? )

2. how i can move program to background - i want no output from program just its running in background ( to close command.com )

Best regards, phantasma -- Dni odlotowych Cen - promocja biletow lotniczych [ http://samoloty.onet.pl/ ]

Reply by email

Stefan Ziegenbalg
to Unknown author

Hi,

if you are using linux try this:

uses crt,linux;
var t: text;
begin
assign(t,'/dev/tty12');
rewrite(t);
case fork of
  0: begin
     repeat
      delay(1000);
      write(t,'T1'#10#13);
      until false;
     end;
  else writeln('Tschö');
  end;
end.

The programm (the first process) exit's after calling. The cloned process outputs `T1' to tty12 until you kill it.

Stefan

----------------------------------------------

http://www.sziegenbalg.de
http://www.simage.org

------------------------------------------------------------------ In a world without walls and fences, who needs Windows and Gates ?

Reply by email

Michael Van Canneyt
to Unknown author: i have two questions : 1. how i can write multithreaded program in free pascal ( using…
Show quoted text 6 lines
Hello fpc-pascal, i have two questions : 1. how i can write multithreaded program in free pascal ( using linux unit and clone function ??? )

You just call clone with the right arguments, and that is it.

2. how i can move program to background - i want no output from program just its running in background ( to close command.com )

Under Linux, just do

If fork0 then
  Exit;

Now the child is running in the background, and the parent has exited.

Michael.

Reply by email

Thomas Schatzl
to Michael Van Canneyt

Hi,

Subject: Re: [fpc-pascal]two questions plz help

Show quoted text 9 lines
> Hello fpc-pascal, > > i have two questions : > > 1. how i can write multithreaded program in free pascal ( using > linux unit and clone function ??? ) You just call clone with the right arguments, and that is it.

Does that mean the RTL is already MT safe ?

Regards,
Thomas

Reply by email

Jonas Maebe
to Thomas Schatzl
Thomas Schatzl wrote 6 lines
>> 1. how i can write multithreaded program in free pascal ( using >> linux unit and clone function ??? ) > > You just call clone with the right arguments, and that is it. Does that mean the RTL is already MT safe ?

No, it's not. So fork() is currently only useful if you do

a) no memory allocation (or if you use a thread-safe heap manager, such as the one in the cmem unit of the packages)
b) no IO
c) no errno error checking

I think the above are the only parts that are not thread safe...

Jonas

Reply by email

Thomas Schatzl
to Jonas Maebe

Subject: Re: [fpc-pascal]two questions plz help

> Does that mean the RTL is already MT safe ? No, it's not. So fork() is currently only useful if you do

I assumed because a developer answered to this question without mentioning this....

a) no memory allocation (or if you use a thread-safe heap manager, such as the one in the cmem unit of the packages)

This includes implicit memory allocations like ansistring handling, object creation, etc. I guess ?

b) no IO c) no errno error checking I think the above are the only parts that are not thread safe...

So if I used a unit like this for Win32 (I remember cmem being Linux only...) everything should be ok ? [Assuming that the Win32 system memory management is threadsafe]

---------------- start of unit
unit win32heap;
interface
{$mode delphi}
implementation
uses
 windows;
function win32getmem(size : longint) : pointer;
begin
 result := HeapAlloc(GetProcessHeap, 0, size);
end;
function win32freemem(var p : pointer) : longint;
begin
 result := HeapSize(GetProcessHeap, 0, p);
 HeapFree(GetProcessHeap, 0, p);
 p := nil;
end;
function win32freememsize(var p : pointer; size : longint) : longint;
begin
 result := win32freemem(p);
end;
function win32allocmem(size : longint) : pointer;
begin
 result := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, size);
end;
function win32reallocmem(var p : pointer; size : longint) : pointer;
begin
 result := HeapReAlloc(GetProcessHeap, 0, p, size);
 if (result  p) then
  win32freemem(p);
end;
function win32memsize(p : pointer) : longint;
begin
 result := HeapSize(GetProcessHeap, 0, p);
end;
function win32memavail : longint;
begin
 result := 0;
end;
function win32maxavail : longint;
begin
 result := 0;
end;
function win32heapsize : longint;
begin
 result := 0;
end;
const
 Win32MemoryManager : TMemoryManager = (
  getmem : @win32Getmem;
  freemem : @win32Freemem;
  freememsize : @win32FreememSize;
  allocmem : @win32Allocmem;
  reAllocmem : @win32ReAllocmem;
  memsize : @win32MemSize;
  memAvail : @win32MemAvail;
  maxAvail : @win32MaxAvail;
  heapSize : @win32Heapsize;
 );
var
 defaultMemoryManager : TMemoryManager;
initialization
begin
 GetMemoryManager(defaultMemoryManager);
 SetMemoryManager(Win32MemoryManager);
end;
finalization
begin
 Writeln('exiting memory manager');
 SetMemoryManager(defaultMemoryManager);
end;
end.
--------- end of unit

Regards,
Thomas

Reply by email

Jonas Maebe
to Thomas Schatzl
Thomas Schatzl wrote 5 lines
> No, it's not. So fork() is currently only useful if you do I assumed because a developer answered to this question without mentioning this....

I know. This has been said so many times, that you can forget it sometimes :) You're correct it should always be mentioned though.

Show quoted text 6 lines
> a) no memory allocation (or if you use a thread-safe heap manager, such > as the one in the cmem unit of the packages) This includes implicit memory allocations like ansistring handling, object creation, etc. I guess ?

Yes, they all use the currently installed heap manager.

Show quoted text 9 lines
> b) no IO > c) no errno error checking > > I think the above are the only parts that are not thread safe... So if I used a unit like this for Win32 (I remember cmem being Linux only...) everything should be ok ? [Assuming that the Win32 system memory management is threadsafe]

Indeed. In fact, I've already heard of someone in the past who was succesful in creating an MT FPC program this way.

Jonas

Reply by email

Thomas Schatzl
to Jonas Maebe

Hi,

I know. This has been said so many times, that you can forget it sometimes :) You're correct it should always be mentioned though.

Sure....

Show quoted text 8 lines
>> I think the above are the only parts that are not thread safe... > > So if I used a unit like this for Win32 (I remember cmem being Linux > only...) everything should be ok ? [Assuming that the Win32 system > memory management is threadsafe] In fact, I've already heard of someone in the past who was succesful in creating an MT FPC program this way.

Well, not me =) Regardless of that, is there still something to do to get FPC MT safe and basically operational ?

Regards,
Thomas

Reply by email

Jonas Maebe
to Thomas Schatzl: Sure.... Well, not me =) Regardless of that, is there still something to do to get FPC MT…
Thomas Schatzl wrote 6 lines
> In fact, I've already heard of someone in the past who was > succesful in creating an MT FPC program this way. Well, not me =) Regardless of that, is there still something to do to get FPC MT safe and basically operational ?

Yes, the inoutres variable (and under Linux, the errno).

I think those are the main obstacles, though any global variable in the system unit can theoretically cause havoc (filemode for example).

Jonas

Reply by email

Stefan Ziegenbalg
to Thomas Schatzl: Sure.... Well, not me =) Regardless of that, is there still something to do to get FPC MT…

Hi,

Thomas Schatzl wrote
Well, not me =) Regardless of that, is there still something to do to get FPC MT safe and basically operational ?

I have some working MT code :-)). At the first time I had some trouble with i/o and mem. It can be solved with bolcking routines. The exception handling ist still a little bit sticky.

Example blocking code:

var lock_mem : boolean;
procedure getmem2(var pt:pointer; size:longint);
bein
while lock_mem do
 delay(1);
lock_mem:=true;
getmem(pt,size);
lock_mem:=false;
end;
procedure freemem2(var pt:pointer; size:longint);
bein
while lock_mem do
 delay(1);
lock_mem:=true;
freemem(pt,size);
lock_mem:=false;
end;

...
...

Regards,
Stefan

----------------------------------------------

http://www.sziegenbalg.de
http://www.simage.org

------------------------------------------------------------------ In a world without walls and fences, who needs Windows and Gates ?

Reply by email

Thomas Schatzl
to Jonas Maebe: Yes, the inoutres variable (and under Linux, the errno). I think those are the main…

Subject: Re: [fpc-pascal]two questions plz help

Show quoted text 7 lines
> Well, not me =) Regardless of that, is there still something to do to > get FPC MT safe and basically operational ? Yes, the inoutres variable (and under Linux, the errno). I think those are the main obstacles, though any global variable in the system unit can theoretically cause havoc (filemode for example).

So _if_ I built my own System unit from scratch (taking care of MT-safeness) everything would be ok ? (Sorry for repeating the question, just to be 100% sure....)

Regards,
Thomas

Reply by email

Marco van de Voort
to Thomas Schatzl: Subject: Re: [fpc-pascal]two questions plz help So _if_ I built my own System unit from…
Show quoted text 11 lines
> > Well, not me =) Regardless of that, is there still something to do to > > get FPC MT safe and basically operational ? > > Yes, the inoutres variable (and under Linux, the errno). > > I think those are the main obstacles, though any global variable in the > system unit can theoretically cause havoc (filemode for example). So _if_ I built my own System unit from scratch (taking care of MT-safeness) everything would be ok ? (Sorry for repeating the question, just to be 100% sure....)

Yes, I think so, maybe except FPU code.

Reply by email

Florian Klaempfl
to Thomas Schatzl: Subject: Re: [fpc-pascal]two questions plz help So _if_ I built my own System unit from…
you wrote 7 lines
Subject: Re: [fpc-pascal]two questions plz help > > Well, not me =) Regardless of that, is there still something to do to > > get FPC MT safe and basically operational ? > > Yes, the inoutres variable

Inoures is thread safe, at least in the common code.

Show quoted text 7 lines
(and under Linux, the errno). > > I think those are the main obstacles, though any global variable in the > system unit can theoretically cause havoc (filemode for example). So _if_ I built my own System unit from scratch (taking care of MT-safeness) everything would be ok ?

Yes. But this isn't necessary. At least the MT-safeness for Win32 in the 1.1 branch should have beta qualitiy, i.e. everything is implemented but it needs to be tested more deeply.

For unix/linux, at least rtl/inc/thread.inc needs some work (no critical sections yet).

(Sorry for repeating the question, just to be 100% sure....)

To enable the MT-safeness, the 1.1 rtl must be compiled with -dMT and I don't think that this will change in the future, i.e. the 1.1 compilers will come with a single threaded rtl, if you want to write MT programs you have to recompile the rtl.

Reply by email

Jonas Maebe
to Stefan Ziegenbalg: I have some working MT code :-)). At the first time I had some trouble with i/o and mem.…
Stefan Ziegenbalg wrote 11 lines
var lock_mem : boolean; procedure getmem2(var pt:pointer; size:longint); bein while lock_mem do delay(1); lock_mem:=true; getmem(pt,size); lock_mem:=false; end; ;

This isn't two threads are in the "while lock_mem do delay(1);" loop, it's possible that when something else sets it to false, they both check it before the other one has set it to true. You need to do the testing and setting as an atomic operation.

Jonas

Reply by email

Stefan Ziegenbalg
to Jonas Maebe
Jonas Maebe wrote
This isn't two threads are in the "while lock_mem do delay(1);" loop, it's possible that when something else sets it to false, they both check it before the other one has set it to true. You need to do the testing and setting as an atomic operation.

But the probability of that event is very low. It can been avoid by setting lock_mem to a thread specific ID (for example the PID):

var lock_mem  : longint;
procedure getmem2(var pt:pointer; size:longint);
var pid:longint;
begin
pid:=getpid; { maybe getpid needs more time than delay(1) }
repeat
 while lock_mem0 do
  delay(1);
 lock_mem:=pid;
 delay(1);
 until lock_mem=pid;
getmem(pt,size);
lock_mem:=0;
end;

I think this should avoid any pathological cases. :-)

Regards
Stefan

----------------------------------------------

http://www.sziegenbalg.de
http://www.simage.org

------------------------------------------------------------------ In a world without walls and fences, who needs Windows and Gates ?

Reply by email

Jonas Maebe
to Stefan Ziegenbalg
Stefan Ziegenbalg wrote 6 lines
> This isn't two threads are in the "while lock_mem do > delay(1);" loop, it's possible that when something else sets it to > false, they both check it before the other one has set it to true. You > need to do the testing and setting as an atomic operation. But the probability of that event is very low.

But it will cause sporadic and very hard to trace crashes. There's no use in making something "almost thread safe" :)

Jonas

Reply by email