Sign in Join

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

Mailing lists / fpc-pascal / 2008-02

Semaphore

14 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

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

Damien Gerard

Hi !
I think it has been discussed before but I would like to use Semaphores, to allow multiple reads but 1 write at once (which is in fact commons operations in a multi-thread program).

My program must work under OSX/Nux and Windows.
I may have missed something but I can not find something suitable for me.
Under Windows OpenSemaphore, under unixes CurrentTM.Semaphore*...

Is there any TSemaphore class of equivalent ? Or may be an example how to use Semaphores ? :)

Damien Gerard Le temps n'a pas d'importance. Seul le code est important -- (f00ty)

Reply by email

Graeme Geldenhuys
to Damien Gerard
Damien Gerard wrote 7 lines
My program must work under OSX/Nux and Windows. I may have missed something but I can not find something suitable for me. Under Windows OpenSemaphore, under unixes CurrentTM.Semaphore*... Is there any TSemaphore class of equivalent ? Or may be an example how to use Semaphores ? :)

I've wondered the same thing.... In the end I had to write code like the following:
Not idea, but it works. We needed to support Linux and Windows only.

procedure TtiPool.CreatePoolSemaphore;
begin
  {$IFDEF MSWINDOWS}
  if FSemaphore  0 then
    CloseHandle(FSemaphore);
  FSemaphore := CreateSemaphore(nil, FMaxPoolSize, FMaxPoolSize, nil);
  {$ENDIF MSWINDOWS}
  {$IFDEF LINUX}
  sem_destroy(FSemaphore);
  if sem_init(FSemaphore, 0, FMaxPoolSize)  0 then
    raise Exception.Create('Failed to create the semaphore');
  {$ENDIF LINUX}
end;

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Damien Gerard
to Graeme Geldenhuys
Graeme Geldenhuys wrote 29 lines
On 11/02/2008, Damien Gerard wrote: > My program must work under OSX/Nux and Windows. > I may have missed something but I can not find something suitable for > me. > Under Windows OpenSemaphore, under unixes CurrentTM.Semaphore*... > > Is there any TSemaphore class of equivalent ? Or may be an example > how > to use Semaphores ? :) I've wondered the same thing.... In the end I had to write code like the following: Not idea, but it works. We needed to support Linux and Windows only. procedure TtiPool.CreatePoolSemaphore; begin {$IFDEF MSWINDOWS} if FSemaphore 0 then CloseHandle(FSemaphore); FSemaphore := CreateSemaphore(nil, FMaxPoolSize, FMaxPoolSize, nil); {$ENDIF MSWINDOWS} {$IFDEF LINUX} sem_destroy(FSemaphore); if sem_init(FSemaphore, 0, FMaxPoolSize) 0 then raise Exception.Create('Failed to create the semaphore'); {$ENDIF LINUX} end;

Thanks !

I think I can safely change LINUX by UNIX and it should work on OS X too.
I will made a TSemaphore :)

Show quoted text 12 lines
Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/ _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Damien Gerard Le temps n'a pas d'importance. Seul le code est important -- (f00ty)

Reply by email

Damien Gerard
to Graeme Geldenhuys: I've wondered the same thing.... In the end I had to write code like the following: Not…
Graeme Geldenhuys wrote 28 lines
On 11/02/2008, Damien Gerard wrote: > My program must work under OSX/Nux and Windows. > I may have missed something but I can not find something suitable for > me. > Under Windows OpenSemaphore, under unixes CurrentTM.Semaphore*... > > Is there any TSemaphore class of equivalent ? Or may be an example > how > to use Semaphores ? :) I've wondered the same thing.... In the end I had to write code like the following: Not idea, but it works. We needed to support Linux and Windows only. procedure TtiPool.CreatePoolSemaphore; begin {$IFDEF MSWINDOWS} if FSemaphore 0 then CloseHandle(FSemaphore); FSemaphore := CreateSemaphore(nil, FMaxPoolSize, FMaxPoolSize, nil); {$ENDIF MSWINDOWS} {$IFDEF LINUX} sem_destroy(FSemaphore); if sem_init(FSemaphore, 0, FMaxPoolSize) 0 then raise Exception.Create('Failed to create the semaphore'); {$ENDIF LINUX} end;

I realize you have already made a TSemaphore like. May be I can directly use it for my purposes ?

Damien Gerard Le temps n'a pas d'importance. Seul le code est important -- (f00ty)

Reply by email

Jonas Maebe
to Damien Gerard: Hi ! I think it has been discussed before but I would like to use Semaphores, to allow…
Damien Gerard wrote 8 lines
I think it has been discussed before but I would like to use Semaphores, to allow multiple reads but 1 write at once (which is in fact commons operations in a multi-thread program). My program must work under OSX/Nux and Windows. I may have missed something but I can not find something suitable for me. Under Windows OpenSemaphore, under unixes CurrentTM.Semaphore*...

CurrentTM.Semaphore* should also work under Windows (if it doesn't, please file a bug report). And the way to use those is by calling

{$ifdef unix}
uses
   cthreads;
{$endif}
var
   p: pointer;
begin
   p:=currenttm.SemaphoreInit;
   currenttm.semaphorepost(p);
   currenttm.semaphorewait(p);
   currenttm.semaphoredestroy(p);
end.

Jonas

Reply by email

Jonas Maebe
to Damien Gerard: Thanks ! I think I can safely change LINUX by UNIX and it should work on OS X too. I will…
Damien Gerard wrote 21 lines
Le Feb 12, 2008 à 12:36 PM, Graeme Geldenhuys a écrit : > procedure TtiPool.CreatePoolSemaphore; > begin > {$IFDEF MSWINDOWS} > if FSemaphore 0 then > CloseHandle(FSemaphore); > FSemaphore := CreateSemaphore(nil, FMaxPoolSize, FMaxPoolSize, nil); > {$ENDIF MSWINDOWS} > {$IFDEF LINUX} > sem_destroy(FSemaphore); > if sem_init(FSemaphore, 0, FMaxPoolSize) 0 then > raise Exception.Create('Failed to create the semaphore'); > {$ENDIF LINUX} > end; > Thanks ! I think I can safely change LINUX by UNIX and it should work on OS X too.

No, you can't, because sem_init does not exist on Mac OS X. Use the RTL implementation, it works on all platforms. Further, the above code looks buggy because it always calls sem_destroy for FSemaphore, even it was not allocated (and that may cause the program to crash, depending on the contents of FSemaphore at that point and the implementation of sem_init).

Jonas

Reply by email

Damien Gerard
to Jonas Maebe
Jonas Maebe wrote 32 lines
On 12 Feb 2008, at 14:20, Damien Gerard wrote: > Le Feb 12, 2008 à 12:36 PM, Graeme Geldenhuys a écrit : > >> procedure TtiPool.CreatePoolSemaphore; >> begin >> {$IFDEF MSWINDOWS} >> if FSemaphore 0 then >> CloseHandle(FSemaphore); >> FSemaphore := CreateSemaphore(nil, FMaxPoolSize, FMaxPoolSize, nil); >> {$ENDIF MSWINDOWS} >> {$IFDEF LINUX} >> sem_destroy(FSemaphore); >> if sem_init(FSemaphore, 0, FMaxPoolSize) 0 then >> raise Exception.Create('Failed to create the semaphore'); >> {$ENDIF LINUX} >> end; >> > > Thanks ! > > I think I can safely change LINUX by UNIX and it should work on OS > X too. No, you can't, because sem_init does not exist on Mac OS X. Use the RTL implementation, it works on all platforms. Further, the above code looks buggy because it always calls sem_destroy for FSemaphore, even it was not allocated (and that may cause the program to crash, depending on the contents of FSemaphore at that point and the implementation of sem_init).
sem_* don't came from pthreads ?
Under OS X you can do
{$ifdef unix}
uses
  cthreads;
{$endif}

I thought it would follow the same behavior. But I agree RTL is my friend :)

Jonas_______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Damien Gerard Le temps n'a pas d'importance. Seul le code est important -- (f00ty)

Reply by email

Damien Gerard
to Jonas Maebe: CurrentTM.Semaphore* should also work under Windows (if it doesn't, please file a bug…
Jonas Maebe wrote 27 lines
On 11 Feb 2008, at 10:45, Damien Gerard wrote: > I think it has been discussed before but I would like to use > Semaphores, to allow multiple reads but 1 write at once (which is > in fact commons operations in a multi-thread program). > > My program must work under OSX/Nux and Windows. > I may have missed something but I can not find something suitable > for me. > Under Windows OpenSemaphore, under unixes CurrentTM.Semaphore*... CurrentTM.Semaphore* should also work under Windows (if it doesn't, please file a bug report). And the way to use those is by calling {$ifdef unix} uses cthreads; {$endif} var p: pointer; begin p:=currenttm.SemaphoreInit; currenttm.semaphorepost(p); currenttm.semaphorewait(p); currenttm.semaphoredestroy(p); end.

I though that too but currenttm can not be found under Windows. What is the good unit for it ?

Damien Gerard Le temps n'a pas d'importance. Seul le code est important -- (f00ty)

Reply by email

Jonas Maebe
to Damien Gerard: sem_* don't came from pthreads ? Under OS X you can do {$ifdef unix} uses cthreads;…
Damien Gerard wrote 10 lines
Le Feb 12, 2008 à 2:44 PM, Jonas Maebe a écrit : > No, you can't, because sem_init does not exist on Mac OS X. Use the > RTL implementation, it works on all platforms. Further, the above > code looks buggy because it always calls sem_destroy for > FSemaphore, even it was not allocated (and that may cause the > program to crash, depending on the contents of FSemaphore at that > point and the implementation of sem_init). > sem_* don't came from pthreads ?

"The sem_init() function is part of the Semaphores option and need not be available on all implementations"

Show quoted text 8 lines
Under OS X you can do {$ifdef unix} uses cthreads; {$endif} I thought it would follow the same behavior. But I agree RTL is my friend :)
cthreads is not required to directly call any posix routines. It is
required to call the RTL versions of the thread-related routines;

Jonas

Reply by email

Graeme Geldenhuys
to Jonas Maebe: CurrentTM.Semaphore* should also work under Windows (if it doesn't, please file a bug…
Jonas Maebe wrote 17 lines
CurrentTM.Semaphore* should also work under Windows (if it doesn't, please file a bug report). And the way to use those is by calling {$ifdef unix} uses cthreads; {$endif} var p: pointer; begin p:=currenttm.SemaphoreInit; currenttm.semaphorepost(p); currenttm.semaphorewait(p); currenttm.semaphoredestroy(p); end.

Thanks Jonas. :) I didn't know about this. I'll update my old code to the above...

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Damien Gerard
to Jonas Maebe: Indeed, you shouldn't use currenttm. Use this routine instead (from the system unit, the…
Jonas Maebe wrote 10 lines
On 12 Feb 2008, at 14:55, Damien Gerard wrote: > I though that too but currenttm can not be found under Windows. > What is the good unit for it ? Indeed, you shouldn't use currenttm. Use this routine instead (from the system unit, the result indicates success or failure): Function GetThreadManager(Var TM : TThreadManager) : Boolean;

Ok thanks ! I ve got all I need to use Semaphore, except one thing : How I set the limit ?
I mean I want to restrict to 4 concurrent accesses to a shared ressource.

With pthread I have
int sem_init(sem_t *sem, int pshared, unsigned int value);
but here we have only
TSempahoreInitHandler     = function: Pointer;

Sorry I have for sure missed something :)

Damien Gerard Le temps n'a pas d'importance. Seul le code est important -- (f00ty)

Reply by email

Jonas Maebe
to Damien Gerard
Damien Gerard wrote 12 lines
Ok thanks ! I ve got all I need to use Semaphore, except one thing : How I set the limit ? I mean I want to restrict to 4 concurrent accesses to a shared ressource. With pthread I have int sem_init(sem_t *sem, int pshared, unsigned int value); but here we have only TSempahoreInitHandler = function: Pointer; Sorry I have for sure missed something :)

Call SemaphorePost 4 times after initialising it.

Jonas

Reply by email

Damien Gerard
to Jonas Maebe
Jonas Maebe wrote 17 lines
On 12 Feb 2008, at 15:43, Damien Gerard wrote: > Ok thanks ! I ve got all I need to use Semaphore, except one > thing : How I set the limit ? > I mean I want to restrict to 4 concurrent accesses to a shared > ressource. > > With pthread I have > int sem_init(sem_t *sem, int pshared, unsigned int value); > > but here we have only > TSempahoreInitHandler = function: Pointer; > > Sorry I have for sure missed something :) Call SemaphorePost 4 times after initialising it.

Oki Thanks !

Damien Gerard Le temps n'a pas d'importance. Seul le code est important -- (f00ty)

Reply by email