?
Solved

Using threads and finite state machines to control script synchronization

Posted on 2007-10-09
10
Medium Priority
?
527 Views
Last Modified: 2008-01-09
Hi,

I have a question (or need for advice) on thread programming that isn't covered by the

conventional tutorials.

I'm a newbie to thread programming. I only worked on one lab project involving Windows

threads in C++ back in college. I like using C# as well but haven't gotten to thread

programming in that language.

It probably behaves like a finite state machine as well, which I've never programmed in C++

or C#. I've only used Verilog for that.

At my workplace, we have an in house tool for synchronizing the execution of certain

commands (in custom script files) using threads. The tool is based on the Intel Dialogic API

and is for phone/PBX testing. It is closely tied to the Dialogic hardware. So I am planning

on writing a subset port of the tool that supports the synchronization (the current tool has

a lot more features than that).

However, I hit some stumbling blocks:

1. The developer of the tool left years back. I managed to find the C++ source code but it

is sparsely commented, somewhat cryptic, and there is no formal documentation. It's well

object oriented but too much such that I can't find the code of interest. I'm still

attempting to analyze it when I have time.

2. The tutorials on the web for threads in C++ or C# don't seem to cover what I'm looking

for.

So I'm hoping someone here can advise me on how I should approach this and where I can find

the info necessary to build such a tool. If possible, I'd like to hear of possible

approaches in both C++ and C#. A cross-platform type of solution would be nice as well, but

I just need it for Windows for now.

Here's what I'm trying to accomplish:

We start with a script file like the following

begin script file
------------------

201; WAIT;
201; EXECUTE; "command here"
201; RELEASE; 202
...

202; EXECUTE; "command here"
202; RELEASE; 201
202; WAIT;
...
----------------
end script file

In this script, 201 & 202 execute in parallel or simultaneously. Because 201 is set to wait

state, only 202 starts initially when the script runs. Later, 202 releases 201, so it can

run. Next sequence for 202 is a wait state as well, so 201 & 202 wait on each other before

execution because the command they execute may depend on the result of the other. However,

this isn't always the case, there may be cases where 202 releases 201 and both then continue

to run as 201 initially depends on 202. And vice versa.

The script file example above is read in by the tool and parsed (into a finite state

machine?) as some data structure. Threads are created for each ID (201, 202, etc.) and the

appropriate data structure is assigned to each thread.

Throughout the lifecycle of each thread, there are 3 things it can do: wait until another

thread releases it, release another thread (by some ID), or execute a command. The command

is simply a system call to the command shell to execute an external program or script.

I can handle the script parsing, data structure setup, and command execution, but I have no

idea where or how to start on the thread synchronization. It doesn't look like a simple

mutex or semaphore will do to control the synchronization per the scripts behavior.
0
Comment
Question by:daluu
10 Comments
 
LVL 10

Expert Comment

by:peetm
ID: 20044212
Ok, so I'm a C/C++/Windows guy - but, when it comes to threads, I'd say if you have to use them, and learn about them, that there's no better place to start than in Java.

Honestly, have a play about with Java's abstract threads before diving into an OS's implementation!  You'll love me for this advice if you follow it!

Paul Hyde's Java Thread Programming [book] is a good resource, and one can very easily port the Java code to C++ later.

Lastly, threads are IMHO intrinsically nasty [and don't start me off on Fibers!].  I've worked on many multi-running [need a better term there] apps in the past, and all were better written as single-threaded processes that used the various inter-process mechanisms OSs supply to communicate with each other.  This also keeps the code far more modular and maintainable in my experience.

BTW, the only multi-threaded stuff I do these days is in Java [coz you'd be a dummy to get it wrong there] - else it's the multiple single-process + inter-process-communication way for me.  Works every time, and everybody's happy!
0
 
LVL 4

Author Comment

by:daluu
ID: 20045097
Thanks, Java is another alternative language to use. But then how would I solve the issue of having a thread waiting to be released by another thread or a thread releasing another thread, something like:

some code for thread A will at some point call wait(). And it waits until it is released by any thread that releases it.

And some code in thread B will at some point call something like this release(idOfThreadB). and that release/resume threadB. The ID is either a reference to thread B's handle or some unique ID that can be used to release threadB.

If this is feasible in Java, C++, or C#, then I can start R&D, otherwise, I'll need to find a solution/framework before continuing.

I don't think what I want can be done without multiple processes or threads as I must run several tasks in parallel that must wait on other tasks at certain points in time.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20046719
>>>> In this script, 201 & 202 execute in parallel or simultaneously.
I can't see that from your description. It looks like thread execution runs exclusively. If so, you need no threads. Just do the 'jobs' into a queue and process the queue using one thread.

If I am right, you have at most two threads. A main thread which reads the script and initially fills the job queue. Then a worker thread which processes the queue. While the worker thread is running the main thread could wait for user input and/or monitor the worker thread's activitities, maybe puuing some more jobs into the job queue. For that - adding to the queue and removing from queue - you would need thread synchronisation simpliest made by a critical section resource.

Regards, Alex
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 22

Assisted Solution

by:NovaDenizen
NovaDenizen earned 80 total points
ID: 20049379
This is an interesting question.

I think the thread feature you're looking for is a condition variable.  A thread calls "wait()" on a condition variable when a "WAIT;" script command is reached, and the current thread is suspended.  When another thread performs a corresponding "RELEASE;" command, it calls notify() on the appropriate condition variable, which causes the suspended thread to eventually wake up and continue execution.

You could also do something equivalent with a semaphore.  Associate a new semaphore with every thead, and initialize each with a count of 0.  A "WAIT;" corresponds to a P operation, and a "RESUME;" corresponds to a V operation.

Before you commit to implementing it one way or another, you should be sure of the exact semantics expected by the scripts.  For instance, what should happen if "201; RELEASE; 202;" occurs before "202; WAIT;"?  Should thread 202 just continue because it has been pre-RELEASEd or should it wait until another "RELEASE; 202;" occurs?  Should an error occur when a RELEASE is performed on a non-waiting thread?
0
 

Accepted Solution

by:
Dorfer32 earned 240 total points
ID: 20050717
Like Nova said, an interesting question.  Interesting enough that I was motivated to write a simple solution in c#.  It is available at https://filedb.experts-exchange.com/incoming/ee-stuff/4976-ConsoleApplication1.zip 

That example solution supports the syntax of script files such as I could determine it from your example (so your example script can be run fine.)  I also added a couple more commands (trace and sleep) to better illustrate what is going on when you run it.  I put in quite a few comments so hopefully it should be clear when you read it.

Basically in the .net world the class you are looking for is "System.Threading.EventWaitHandle".  Threads can call "Wait()" on instances of this class and will be paused until another thread calls the "Set()" method.
0
 
LVL 4

Author Comment

by:daluu
ID: 20052866
Thanks for the recent comments, especially from Dorfer32 and NovaDenizen. I will look into your suggestions and try the code sample posted.

A brief update on new findings and responses to comments:

1. NovaDenizen brought up good concerns that were addressed by the old/original tool that I will have to address as well. The initial post was for a simple case. The script can support more than 2 devices/threads--the wait command is the same as posted but the release command supports multiple threads like

201; RELEASE; 202; 203; 204

In the original tool, calling release on a thread that isn't waiting (or before it goes into waiting) will have no effect, it continues to run. But if the corresponding release is called before the wait, the waiting thread will be stuck and the program will have to be terminated and re-run to fix the problem. This is expected though as the input script should be written correctly in the first place. The program only executes what is specified in the input script.


2. I analyzed the original source code a bit yesterday and found some useful information, but still not enough for me. The snippets below relate to the wait and release functions and it appears to be using semaphores with events? Unfortunately, the code is so abstracted that I haven't pinpointed where or how the code snippets tie into the rest of the program's code. If you have some insight on this, I would appreciate it.

//relevant code in function that signals thread to wait
//...
stringstream ss;
ss << fDevice.fName << "; CMD" << "; Wait; ";
if (-1 == fTimeOut) {
    ss << "infinite";
} else {
    ss <<  fTimeOut;
}
//...
HANDLE ha[2];
ha[0] = fDevice.fCfg.fStopEvt;
ha[1] = fDevice.fWaitEvent;
WaitForMultipleObjects(2, ha, FALSE, fTimeOut*1000);
ResetEvent(fDevice.fWaitEvent);

ss.str("");
ss << fDevice.fName << "; RET" << "; Wait; Released";
//...
return true;


//relevant code in function that signals thread to release some other waiting thread
stringstream ss;
ss << fDevice.fName << "; CMD" << "; Release";

int size = fRelease.size();
for (int x=0; x < size; x++) {
    ss << "; " << fRelease[x]->fName;
    SetEvent(fRelease[x]->fWaitEvent);
}
//...
return true;
0
 
LVL 4

Author Comment

by:daluu
ID: 20053191
Thanks for the code sample Dorfer32. This is something I can work with. Easy to follow as well.

I'm going to start working with it and see how well that goes.
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 80 total points
ID: 20054889
>>>> it appears to be using semaphores with events?
no semaphores, only events.

>>>> ha[0] = fDevice.fCfg.fStopEvt;
>>>> ha[1] = fDevice.fWaitEvent;
>>>> WaitForMultipleObjects(2, ha, FALSE, fTimeOut*1000);

The first event handle to wait for is a overall stop event which most likely was used to smoothly terminate all threads at end of prog.

The second event handle is the handle specific for that thread. WaitForMultipleObjects will wait until either event was fired (the 3. argument FALSE says "wait for handle 1 *or* handle 2").

>>>> ResetEvent(fDevice.fWaitEvent);
sets the event to nonsignaled. So, coming back to WaitForMultipleObjects would block the thread again, until the event was signaled again by SetEvent.

>>>> ss << fDevice.fName << "; CMD" << "; Release";
The stringstream operations don't seem to have a meaning beside of logging or beside of updating a script file.

Regards, Alex

0
 
LVL 4

Author Comment

by:daluu
ID: 20059635
Thanks for the analysis. I was thinking it was something like that. I knew the stringstream code was for logging and kept it with the code snippet for reference.

While on the subject, can you or someone point me to books or online articles about using events for synchronization in C++? I'd like to learn more and also to compare with events in C#.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20064359
eventhandling is not difficult. You create an event calling CreateEvent, set it by SetEvent and release it by ReleaseEvent. Look for example at

http://msdn2.microsoft.com/en-us/library/ms686211.aspx to learn more.

Regards, Alex
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Hello there! As a developer I have modified and refactored the unit tests which was written by fellow developers in the past. On the course, I have gone through various misconceptions and technical challenges when it comes to implementation. I would…
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question