Trouble with threads

Linux specific forum
wombats
Enthusiast
Enthusiast
Posts: 663
Joined: Thu Dec 29, 2011 5:03 pm

Trouble with threads

Post by wombats »

Hi,

I'm having a lot of trouble with threads on Linux. I have created a shared library that when the main program tells it to, launches an external program and runs a thread to monitor when the program has stopped. When the program does stop, however, the main program freezes and becomes unresponsive.

Both the main program and shared library have "Create threadsafe executable" enabled.

Am I doing something wrong? It all works fine on Windows and macOS.

Code: Select all

ProcedureDLL StartExternalProgram(path$, output$)
  myProgram = RunProgram(path$, output$, "", #PB_Program_Open)
  If IsProgram(myProgram)
    myProgramThread = CreateThread(@ThreadProcedure(), 0)
  EndIf
EndProcedure
This is ThreadProcedure:

Code: Select all

Procedure ThreadProcedure(*Value)
  If IsProgram(myProgram)
    Repeat
      Delay(20)
    Until ProgramRunning(myProgram) = 0
  EndIf
  Stop()
EndProcedure
And this is the Stop procedure:

Code: Select all

ProcedureDLL Stop()
  SendMainProgramSignal(1) ; Tell main program the program has exited
  If IsProgram(myProgram) And ProgramRunning(myProgram)
    KillProgram(myProgram)
    CloseProgram(myProgram)
  EndIf
EndProcedure
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Trouble with threads

Post by IdeasVacuum »

...could be the issue is using Kill Program before Close Program?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
wombats
Enthusiast
Enthusiast
Posts: 663
Joined: Thu Dec 29, 2011 5:03 pm

Re: Trouble with threads

Post by wombats »

It still happens if I switch them around. If I take out KillProgram, I get an IMA. With only KillProgram, it doesn't give me an IMA, but does freeze.

It doesn't freeze or give me an IMA if I comment out the call to Stop() in ThreadProcedure...but without that, how do I tell the main program that the external program has closed? My shared library doesn't open any windows or have its own event loop, so can I use PostEvent? Or is there another way?
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Trouble with threads

Post by IdeasVacuum »

Just off the top of my head

The thread procedure is the one that detects the external program has finished. So let's try CloseProgram() from there. The Thread can update a Global Var igExternalClosed = #True, which any other part of the main program can check periodically.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Trouble with threads

Post by skywalk »

I have to control a few external programs and the most stable and quickest coding method was a file based handshake. TCP/UDP was an option but more complex to implement between developers. It depends on the speed required for your implementation.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
wombats
Enthusiast
Enthusiast
Posts: 663
Joined: Thu Dec 29, 2011 5:03 pm

Re: Trouble with threads

Post by wombats »

Regarding calling KillProgram before CloseProgram, I checked the manual and it says that's what you're supposed to do.
IdeasVacuum wrote:Just off the top of my head

The thread procedure is the one that detects the external program has finished. So let's try CloseProgram() from there. The Thread can update a Global Var igExternalClosed = #True, which any other part of the main program can check periodically.
I just tried this and it seems to work great. Thanks for the idea!
skywalk wrote:I have to control a few external programs and the most stable and quickest coding method was a file based handshake. TCP/UDP was an option but more complex to implement between developers. It depends on the speed required for your implementation.
Would a file based handshake be each program updating a file based on whether it's running or not? I wouldn't know where to start with TCP/UDP between two apps. I might need to look into that in the future. Do you know any good examples for that?
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Trouble with threads

Post by skywalk »

If you are the author of the external program, then it is simple.
Write a "MyApp.run" file to some non-privileged folder(no Admin required).
MyApp.exe looks for the presence of "MyApp.run". If found, then it does something.
After doing something, MyApp.exe writes "MyApp.ran".
There are many variations, and you can add data to the contents of the files if you need.
Avoid using the Clipboard for this action, since you cannot guarantee the user, or another app will alter the clipboard.
TCP/UDP examples were done by mk-soft and maybe infratec?
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Trouble with threads

Post by IdeasVacuum »

I see that about CloseProgram() - that function is effectively misnamed since it isn't closing the program, it's closing the connection. :shock:
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
wombats
Enthusiast
Enthusiast
Posts: 663
Joined: Thu Dec 29, 2011 5:03 pm

Re: Trouble with threads

Post by wombats »

skywalk wrote:If you are the author of the external program, then it is simple.
Write a "MyApp.run" file to some non-privileged folder(no Admin required).
MyApp.exe looks for the presence of "MyApp.run". If found, then it does something.
After doing something, MyApp.exe writes "MyApp.ran".
There are many variations, and you can add data to the contents of the files if you need.
Avoid using the Clipboard for this action, since you cannot guarantee the user, or another app will alter the clipboard.
TCP/UDP examples were done by mk-soft and maybe infratec?
Ah, thanks. That's an interesting way of doing it. I would never use the clipboard since that is for the user's use. I would never want to risk overwriting something important.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Trouble with threads

Post by IdeasVacuum »

.... you could also use shared memory.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Trouble with threads

Post by Trond »

Your ThreadProcedure() checks myProgram, which is a variable local to StartExternalProgram().

Most likely your problem is in the SendMainProgramSignal() procedure.

Also, why not use #PB_Program_Wait?

Code: Select all

Structure Rundata
  Path.s
  Output.s
EndStructure

Procedure RunProgramNotifyOnEnd(*Rundata.Rundata)
  RunProgram(*Rundata\Path, *Rundata\Output, "", #PB_Program_Wait)
  FreeMemory(*Rundata)
  NotifyMainThread(1)
EndProcedure

ProcedureDLL StartExternalProgram(path$, output$)
  *R.Rundata = AllocateStructure(Rundata)
  *R\Path = path$
  *R\Output = output$
  CreateThread(@RunProgramNotifyOnEnd(), *R)
EndProcedure
Edit: Remember that any procedure you call from a thread, is also running in that thread.
Post Reply