When writing multiple processes in Contiki, it is usual to poll a process and wait for its exit or a continue signal. However, if I need to wait for a specific processes to end and I have events being triggered by multiple processes, how can I get to the source process which created that event? For example, in the following code, I would like to know which process has just exited so that P3 can move ahead.
Here is a common case:
PROCESS_THREAD(&P1,ev,data){
PROCESS_BEGIN();
//Do Something
PROCESS_END();//Posts an EXITED event
}
PROCESS_THREAD(&P2,ev,data){
PROCESS_BEGIN();
//Do Something
PROCESS_END();//Also posts an EXITED event
}
PROCESS_THREAD(&P3,ev,data){
PROCESS_BEGIN();
if(ev==PROCESS_EXITED_EVENT){
//Do Something only upon the exit of PROCESS 2
//However this if block works at the exit of either P1 or P2
}
PROCESS_END();
}
There are other ways, I can do a while loop until both process_is_running(&P1) and process_is_running(&P2) are false. But the ev comparison approach with a small addition to the Process handle would be far more elegant and readable.
I could not get any hints from the Contiki source code. Has any one tried an alternative like the one I hinted above?
I believe the data argument is a pointer to the process that has exited. So this should work:
if(ev == PROCESS_EXITED_EVENT && data == &P2) {
printf("process 2 exited\n");
}
I figured out one more approach. Contiki has a semaphore library, that can be used to wait for a signal on some mutex process. Here is the link.
The idea will be to basically initiate a semaphore at the beginning of P3, make P3 wait for it to be released. I can release it only in P2 and not in P1.
I shall post the code after I test out the solution.
Related
The following simple Promise is vowed and I am not allowed to break it.
my $my_promise = start {
loop {} # or sleep x;
'promise response'
}
say 'status : ', $my_promise.status; # status : Planned
$my_promise.break('promise broke'); # Access denied to keep/break this Promise; already vowed
# in block <unit> at xxx line xxx
Why is that?
Because the Promise is vowed, you cannot change it: only something that actually has the vow, can break the Promise. That is the intent of the vow functionality.
What are you trying to achieve by breaking the promise as you showed? Is it to stop the work being done inside of the start block? Breaking the Promise would not do that. And the vow mechanism was explicitly added to prevent you from thinking it can somehow stop the work inside a start block.
If you want work inside a start block to be interruptible, you will need to add some kind of semaphore that is regularly checked, for instance:
my int $running = 1;
my $my_promise = start {
while $running {
# do stuff
}
$running
}
# do other stuff
$running = 0;
await $my_promise;
Hope this made sense.
The reason why you cannot directly keep/break Promise from outside or stop it on Thread Pool are explained here in Jonathans comment.
Common misuse of Promises comes from timeout pattern.
await Promise.anyof(
start { sleep 4; say "finished"; },
Promise.in( 1 )
);
say "moving on...";
sleep;
This will print "finished". And when user realize that the next logical step for him is to try to kill obsolete Promise. While the only correct way to solve it is to make Promise aware that its work is no longer needed. For example through periodically checking some shared variable.
Things gets complicated if you have blocking code on Promise (for example database query) that runs for too long and you want to terminate it from main thread. That is not doable on Promises. All you can do is to ensure Promise will run in finite time (for example on MySQL by setting MAX_EXECUTION_TIME before running query). And then you have choice:
You can grind your teeth and patiently wait for Promise to finish. For example if you really must disconnect database in main thread.
Or you can move on immediately and allow "abandoned" Promise to finish on its own, without ever receiving its result. In this case you should control how many of those Promises can stack up in background by using Semaphore or running them on dedicated ThreadPoolScheduler.
It looks like if you create a subprocess via exec.Cmd and Start() it, the Cmd.Process field is populated right away, however Cmd.ProcessState field remains nil until the process exits.
// ProcessState contains information about an exited process,
// available after a call to Wait or Run.
ProcessState *os.ProcessState
So it looks like I can't actually check the status of a process I Start()ed while it's still running?
It makes no sense to me ProcessState is set when the process exits. There's an ProcessState.Exited() method which will always return true in this case.
So I tried to go this route instead: cmd.Process.Pid field exists right after I cmd.Start(), however it looks like os.Process doesn't expose any mechanisms to check if the process is running.
os.FindProcess says:
On Unix systems, FindProcess always succeeds and returns a Process for the given pid, regardless of whether the process exists.
which isn't useful –and it seems like there's no way to go from os.Process to an os.ProcessState unless you .Wait() which defeats the whole purpose (I want to know if the process is running or not before it has exited).
I think you have two reasonable options here:
Spin off a goroutine that waits for the process to exit. When the wait is done, you know the process exited. (Positive: pretty easy to code correctly; negative: you dedicate an OS thread to waiting.)
Use syscall.Wait4() on the published Pid. A Wait4 with syscall.WNOHANG set returns immediately, filling in the status.
It might be nice if there were an exported os or cmd function that did the Wait4 for you and filled in the ProcessState. You could supply WNOHANG or not, as you see fit. But there isn't.
The point of ProcessState.Exited() is to distinguish between all the various possibilities, including:
process exited normally (with a status byte)
process died due to receiving an unhandled signal
See the stringer for ProcessState. Note that there are more possibilities than these two ... only there seems to be no way to get the others into a ProcessState. The only calls to syscall.Wait seem to be:
syscall/exec_unix.go: after a failed exec, to collect zombies before returning an error; and
os/exec_unix.go: after a call to p.blockUntilWaitable().
If it were not for the blockUntilWaitable, the exec_unix.go implementation variant for wait() could call syscall.Wait4 with syscall.WNOHANG, but blockUntilWaitable itself ensures that this is pointless (and the goal of this particular wait is to wait for exit anyway).
I'm working on a project where I need to implement some sort of termination detection via a variable which changes only in the root process of an MPI program.
I am struggling to understand the concepts of blocking and non-blocking instructions.
In short, only the root process can determine if the task has been completed or not. This is done by implementing a simple Boolean integer variable called "running". This has to be broadcasted to all processes in order for them to know when to exit their while-loops.
All processes run in their own while-loop. At the start, the root process sets the "running" variable to true if necessary.
The root process can then determine if the "running" variable should be set to zero and should broadcast it to all other processes.
Currently, I am using a broadcast to share this variable. Thus, whenever the loop reaches its end (or "running" gets set to zero) it broadcasts the value to all processes. Thus, each process has a broadcast inside of their function to receive the value.
I am either misunderstanding the concept of blocking or my program is not efficient.
Broadcast is blocking, thus, if the root keeps on broadcasting the variable that essentially stays the same (TRUE) for the majority of the running time, each process will essentially have to wait for the root to complete its work and then block before that process can continue with its future work.
The problem exists that since this variable only changes once in the root process, there are many unnecessary blocks happening while running. I only want the variable to be broadcasted once it has been changed to zero so that I can tell the other processes to terminate a part of their code and not have to wait for the root to broadcast every time.
if(myRank != 0) {
while(running) {
doThisFunction(myRank);
MPI_Broadcast(... running ...); //Wait for root to broadcast?
}
/* Start doing something else */
} else {
while(running || ... ) {
/* Do stuff */
if (...) {
running = 0; //Somewhere in an if statement
MPI_Broadcast(... running ...); //Now terminate the while
}
MPI_Broadcast(... running ...); //Unnecessary broadcast?
}
}
I was thinking that I could use MPI_IProbe to check if there's a message to be received and then removing the MPI_Broadcast in the root's while-loop. If there is, then the process will initiate an MPI_Broadcast. If not, then it will continue as normal.
TL;DR:
My program terminates some code in processes if "running" equals zero. Currently, it broadcasts this in every while iteration and I think this causes the program to have an unnecessary block. I only want to send/ receive the variable when it is changed in the root.
Thanks for the help!
edit: "running" is a global variable.
I have two threads of execution like,
Routine 1 {
// do something
}
Routine 2 {
// do something
}
Is it possible to pause execution of routine 2 from routine 1 for few seconds and how can it possible ?
It is not possible to control the execution of one goroutine from another. Goroutines are cooperative. They don't dominate each other.
What you could do is put points in routine 2 where it checks whether it's allowed to proceed. Such as
// do stuff
select {
case <-wait:
<-resume
default:
}
Then routine 1 could tell routine 1 could send a signal to routine 2 telling it to wait:
wait <- true
// whatever stuff goes here
resume <- true
Why do you want to pause the goroutine? That might help answer your question better. It is best to start from a place of what you are trying to do rather than how you want to do it. That way, you can find out how to achieve what you actually want in the language, rather than being given poor substitutes for the method of achieving it that you'd originally imagined.
From one thread, it is not possible to control another thread implicitly. You can do like this, define a bool and based on that you can pause by time.Sleep(2*1e9).
I have a thread that, when its function exits its loop (the exit is triggered by an event), it does some cleanup and then sets a different event to let a master thread know that it is done.
However, under some circumstances, SetEvent() seems not to return after it sets the thread's 'I'm done' event.
This thread is part of a DLL and the problem seems to occur after the DLL has been loaded/attached, the thread started, the thread ended and the DLL detached/unloaded a number of times without the application shutting down in between. The number of times this sequence has to be repeated before this problem happens is variable.
In case you are skeptical that I know what I'm talking about, I have determined what's happening by bracketing the SetEvent() call with calls to OutputDebugString(). The output before SetEvent() appears. Then, the waiting thread produces output that indicates that the Event has been set.
However, the second call to OutputDebugString() in the exiting thread (the one AFTER SetEvent() ) never occurs, or at least its string never shows up. If this happens, the application crashes a few moments later.
(Note that the calls to OutputDebugString() were added after the problem started occurring, so it's unlikely to be hanging there, rather than in SetEvent().)
I'm not entirely sure what causes the crash, but it occurs in the same thread in which SetEvent() didn't return immediately (I've been tracking/outputting the thread IDs). I suppose it's possible that SetEvent() is finally returning, by which point the context to which it is returning is gone/invalid, but what could cause such a delay?
It turns out that I've been blinded by looking at this code for so long, and it didn't even occur to me to check the return code. I'm done looking at it for today, so I'll know what it's returning (if it's returning) on Monday and I'll edit this question with that info then.
Update: I changed the (master) code to wait for the thread to exit rather than for it to set the event, and removed the SetEvent() call from the slave thread. This changed the nature of the bug: now, instead of failing to return from SetEvent(), it doesn't exit the thread at all and the whole thing hangs.
This indicates that the problem is not with SetEvent(), but something deeper. No idea what, yet, but it's good not to be chasing down that blind alley.
Update (Feb 13/09):
It turned out that the problem was deeper than I thought when I asked this question. jdigital (and probably others) has pretty much nailed the underlying problem: we were trying to unload a thread as part of the process of detaching a DLL.
This, as I didn't realize at the time, but have since found out through research here and elsewhere (Raymond Chen's blog, for example), is a Very Bad Thing.
The problem was, because of the way it was coded and the way it was behaving, it not obvious that that was the underlying problem - it was camouflaged as all sorts of other Bad Behaviours that I had to wade through.
Some of the suggestions here helped me do that, so I'm grateful to everyone who contributed. Thank you!
Who is unloading the DLL and at what time is the unload done? I am wondering if there is a timing issue here where the DLL is unloaded before the thread has run to completion.
Are you dereferncing a HANDLE * to pass to SetEvent? It's more likely that the event handle reference is invalid and the crash is an access violation (i.e., accessing garbage).
You might want to use WinDbg to catch the crash and examine the stack.
Why do you need to set an event in the slave thread to trigger to the master thread that the thread is done? just exit the thread, the calling master thread should wait for the worker thread to exit, example pseudo code -
Master
{
TerminateEvent = CreateEvent ( ... ) ;
ThreadHandle = BeginThread ( Slave, (LPVOID) TerminateEvent ) ;
...
Do some work
...
SetEvent ( TerminateEvent ) ;
WaitForSingleObject ( ThreadHandle, SOME_TIME_OUT ) ;
CloseHandle ( TerminateEvent ) ;
CloseHandle ( ThreadHandle ) ;
}
Slave ( LPVOID ThreadParam )
{
TerminateEvent = (HANDLE) ThreadParam ;
while ( WaitForSingleObject ( TerminateEvent, SOME__SHORT_TIME_OUT ) == WAIT_TIMEOUT )
{
...
Do some work
...
}
}
There are lots of error conditions and states to check for but this is the essence of how I normally do it.
If you can get hold of it, get this book, it changed my life with respect to Windows development when I first read it many, many years ago.
Advanced Windows: The Developer's Guide to the Win32 Api for Windows Nt 3.5 and Windows 95 (Paperback), by Jeffrey Richter (Author)