create a process tree in C - process

How would I approach creating a process hierarchy that would look like a balanced ternary tree of depth N? ... meaning each process has 3 children so there would be (3^N-1)/2 processes in a tree of depth N. To create the new processes, I only want to use fork().
This is what I have so far but I don't think it works because I don't deal with process IDs and also I really don't think I should do this recursively:
void createTernaryTree(int n) {
if((n-1) == 0) return;
else {
int x;
for(x=0; x<3; x++) {
fork();
createTernaryTree(n-1);
}
}
}
Thanks,
Hristo

This bit does not look right to me:
for(x=0; x<3; x++) {
fork();
createTernaryTree(n-1);
}
The problem is that both the parent and the child continue looping and do the recursion.
Based on the return from fork (0 in the child, > 0 in the parent, -1 on error), you should decide whether to loop or recurse.

The code shown would do the job The code shown would nearly do the job (but there's a subtle problem). The other difficulty would be showing that it does the job.
The problem is that the code doesn't behave differently for the child and the parent processes after the fork. The parent process needs to complete its loop. Each child needs to restart a loop at the next level:
for (int x = 0; x < 3; x++) // C99
{
if (fork() == 0)
{
createTernaryTree(n-1);
break; // Per comment from R Samuel Klatchko
}
}
pause(); // See below
You could (should) add a 'pause();' call after the loop; this would send the parent process into suspended animation until it receives a signal. You could then show that you have a tree of processes. Alternatively, use 'sleep(30)' or some other way of suspending the processes. You don't want them to exit immediately; they'll do that too quickly for you to be able to demonstrate the tree structure.
In theory, you might want to track whether 'fork()' succeeds; in practice, it isn't clear what you'd do differently except, perhaps, not try to create the second child if the first fails (but that's likely to fail anyway, so blindly trying is probably best in the circumstances - but remember that in other situations, it would usually matter a lot).
Trees are inherently recursive structures; using recursion to manage them is often the neatest way to deal with them. This looks like it is tail recursion which means that it can be converted into a looping structure fairly easily. However, managing a data structure to keep tabs on what is happening is going to be harder than just doing it recursively.

Related

What is the time complexity of below function?

I was reading book about competitive programming and was encountered to problem where we have to count all possible paths in the n*n matrix.
Now the conditions are :
`
1. All cells must be visited for once (cells must not be unvisited or visited more than once)
2. Path should start from (1,1) and end at (n,n)
3. Possible moves are right, left, up, down from current cell
4. You cannot go out of the grid
Now this my code for the problem :
typedef long long ll;
ll path_count(ll n,vector<vector<bool>>& done,ll r,ll c){
ll count=0;
done[r][c] = true;
if(r==(n-1) && c==(n-1)){
for(ll i=0;i<n;i++){
for(ll j=0;j<n;j++) if(!done[i][j]) {
done[r][c]=false;
return 0;
}
}
count++;
}
else {
if((r+1)<n && !done[r+1][c]) count+=path_count(n,done,r+1,c);
if((r-1)>=0 && !done[r-1][c]) count+=path_count(n,done,r-1,c);
if((c+1)<n && !done[r][c+1]) count+=path_count(n,done,r,c+1);
if((c-1)>=0 && !done[r][c-1]) count+=path_count(n,done,r,c-1);
}
done[r][c] = false;
return count;
}
Here if we define recurrence relation then it can be like: T(n) = 4T(n-1)+n2
Is this recurrence relation true? I don't think so because if we use masters theorem then it would give us result as O(4n*n2) and I don't think it can be of this order.
The reason, why I am telling, is this because when I use it for 7*7 matrix it takes around 110.09 seconds and I don't think for n=7 O(4n*n2) should take that much time.
If we calculate it for n=7 the approx instructions can be 47*77 = 802816 ~ 106. For such amount of instruction it should not take that much time. So here I conclude that my recurrene relation is false.
This code generates output as 111712 for 7 and it is same as the book's output. So code is right.
So what is the correct time complexity??
No, the complexity is not O(4^n * n^2).
Consider the 4^n in your notation. This means, going to a depth of at most n - or 7 in your case, and having 4 choices at each level. But this is not the case. In the 8th, level you still have multiple choices where to go next. In fact, you are branching until you find the path, which is of depth n^2.
So, a non tight bound will give us O(4^(n^2) * n^2). This bound however is far from being tight, as it assumes you have 4 valid choices from each of your recursive calls. This is not the case.
I am not sure how much tighter it can be, but a first attempt will drop it to O(3^(n^2) * n^2), since you cannot go from the node you came from. This bound is still far from optimal.

How to avoid usize going negative?

I'm translating a chunk (2000 lines) of proprietary C code into Rust. In C, it is common to run a pointer, array index, etc. down, for as long as it is non-negative. In Rust, simplified to the bone, it would look something like:
while i >= 0 && more_conditions {
more_work;
i -= 1;
}
Of course, when i is usize, you get an under-overflow from subtraction. I have learned to work around this by using for loops with .rev(), offsetting my indexes by one, or using a different type and casting with as usize, etc.
Usually it works, and usually I can make it legible, but the code I'm modifying is chock-full of indexes running towards each other, and eventually tested with i_low > i_high
Something like (in Rust)
loop {
while condition1(i_low) { i_low += 1; }
while condition2(i_high) { j_high -= 1; }
if i_low > i_high { return something; }
do_something_else;
}
Every now and then this panics, as i_high runs past 0.
I have been inserting a lot of j_high >= 0 && in the code, and it become a lot less readable.
How do experienced Rust programmers avoid usize variables going to -1?
for loops? for i in (0..size).rev()
casting? i as usize, after checking for i < 0
offsetting your variable by one, and using i-1 when safe?
extra conditionals?
catching exceptions?
Or do you just eventually learn to write programs around these situations?
Clarification: The C code is not broken - it has been supposedly in production for ten years, structuring video segments on multiple servers 24/7. It is just not following Rust conventions - it often returns -1 as an index, it recurses with -1 for the low index of an array to process, and indexes go negative all the time. All of these are handled before problems occurs - ugly, but functional. Something like:
incident_segment = detect_incident(array, start, end);
attach(array, incident_segment);
store(array, start, incident_segment - 1);
process(array, incident_segment + 1, end);
In the above code, every single of the three resulting calls may be getting a segment index that's -1 (attach, store) or out of bounds (process) It's handled, but after the call.
My Rust code appears to be working as well. As a matter of fact, in order to deal with the negative usize, I added additional logic that pruned a number of recursions, so it runs about as fast as the C code (apparently faster, but that's also because I distributed the output on multiple drives)
The issue is that the client does not not want a full rewrite, and wants the 'native' programmers to be able to check the two programs against each other. Based on the answers so far, I'm thinking that using i64 and casting/shadowing as needed may be the best way to produce code that's easy to read for the 'natives'. Which I personally do not have to like...
If you want to do it idiomatically:
for j in (0..=i).rev() {
if conditions {
break;
}
//use j as your new i here
}
Note the use of ..=i here in the iterator, this means that it'll actually iterate including i: [0, 1, 2, ..., i-1, i], otherwise, you end up with [0, 1, 2, ..., i-2, i-1]
Otherwise, here is the code:
while (i as isize - 1) != -2 && more_conditions {
more_work;
i -= 1;
}
playground
I'd probably start by using saturating_sub (and _add for parallel structure):
while condition1(i_low) { i_low = i_low.saturating_add(1); }
while condition2(i_high) { j_high = j_high.saturating_sub(1); }
You need to be careful to ensure that your logic handles the value saturating at zero. You could also use more C-like semantics with wrapping_sub.
Truthfully, there's no one-size-fits-all solution. Many times, complicated logic becomes simpler if you abstract it a bit, or turn it slightly sideways. You haven't provided any concrete examples, so we cannot give any useful advice. I solve way too many problems with iterators, so that's often my first solution.
catching exceptions
Absolutely not. That's exceedingly inefficient and non-idiomatic.

Is it safe, to share an array between threads?

Is it safe, to share an array between promises like I did it in the following code?
#!/usr/bin/env perl6
use v6;
sub my_sub ( $string, $len ) {
my ( $s, $l );
if $string.chars > $len {
$s = $string.substr( 0, $len );
$l = $len;
}
else {
$s = $string;
$l = $s.chars;
}
return $s, $l;
}
my #orig = <length substring character subroutine control elements now promise>;
my $len = 7;
my #copy;
my #length;
my $cores = 4;
my $p = #orig.elems div $cores;
my #vb = ( 0..^$cores ).map: { [ $p * $_, $p * ( $_ + 1 ) ] };
#vb[#vb.end][1] = #orig.elems;
my #promise;
for #vb -> $r {
#promise.push: start {
for $r[0]..^$r[1] -> $i {
( #copy[$i], #length[$i] ) = my_sub( #orig[$i], $len );
}
};
}
await #promise;
It depends how you define "array" and "share". So far as array goes, there are two cases that need to be considered separately:
Fixed size arrays (declared my #a[$size]); this includes multi-dimensional arrays with fixed dimensions (such as my #a[$xs, $ys]). These have the interesting property that the memory backing them never has to be resized.
Dynamic arrays (declared my #a), which grow on demand. These are, under the hood, actually using a number of chunks of memory over time as they grow.
So far as sharing goes, there are also three cases:
The case where multiple threads touch the array over its lifetime, but only one can ever be touching it at a time, due to some concurrency control mechanism or the overall program structure. In this case the arrays are never shared in the sense of "concurrent operations using the arrays", so there's no possibility to have a data race.
The read-only, non-lazy case. This is where multiple concurrent operations access a non-lazy array, but only to read it.
The read/write case (including when reads actually cause a write because the array has been assigned something that demands lazy evaluation; note this can never happen for fixed size arrays, as they are never lazy).
Then we can summarize the safety as follows:
| Fixed size | Variable size |
---------------------+----------------+---------------+
Read-only, non-lazy | Safe | Safe |
Read/write or lazy | Safe * | Not safe |
The * indicating the caveat that while it's safe from Perl 6's point of view, you of course have to make sure you're not doing conflicting things with the same indices.
So in summary, fixed size arrays you can safely share and assign to elements of from different threads "no problem" (but beware false sharing, which might make you pay a heavy performance penalty for doing so). For dynamic arrays, it is only safe if they will only be read from during the period they are being shared, and even then if they're not lazy (though given array assignment is mostly eager, you're not likely to hit that situation by accident). Writing, even to different elements, risks data loss, crashes, or other bad behavior due to the growing operation.
So, considering the original example, we see my #copy; and my #length; are dynamic arrays, so we must not write to them in concurrent operations. However, that happens, so the code can be determined not safe.
The other posts already here do a decent job of pointing in better directions, but none nailed the gory details.
Just have the code that is marked with the start statement prefix return the values so that Perl 6 can handle the synchronization for you. Which is the whole point of that feature.
Then you can wait for all of the Promises, and get all of the results using an await statement.
my #promise = do for #vb -> $r {
start
do # to have the 「for」 block return its values
for $r[0]..^$r[1] -> $i {
$i, my_sub( #orig[$i], $len )
}
}
my #results = await #promise;
for #results -> ($i,$copy,$len) {
#copy[$i] = $copy;
#length[$i] = $len;
}
The start statement prefix is only sort-of tangentially related to parallelism.
When you use it you are saying, “I don't need these results right now, but probably will later”.
That is the reason it returns a Promise (asynchrony), and not a Thread (concurrency)
The runtime is allowed to delay actually running that code until you finally ask for the results, and even then it could just do all of them sequentially in the same thread.
If the implementation actually did that, it could result in something like a deadlock if you instead poll the Promise by continually calling it's .status method waiting for it to change from Planned to Kept or Broken, and only then ask for its result.
This is part of the reason the default scheduler will start to work on any Promise codes if it has any spare threads.
I recommend watching jnthn's talk “Parallelism, Concurrency,
and Asynchrony in Perl 6”.
slides
This answer applies to my understanding of the situation on MoarVM, not sure what the state of art is on the JVM backend (or the Javascript backend fwiw).
Reading a scalar from several threads can be done safely.
Modifying a scalar from several threads can be done without having to fear for a segfault, but you may miss updates:
$ perl6 -e 'my $i = 0; await do for ^10 { start { $i++ for ^10000 } }; say $i'
46785
The same applies to more complex data structures like arrays (e.g. missing values being pushed) and hashes (missing keys being added).
So, if you don't mind missing updates, changing shared data structures from several threads should work. If you do mind missing updates, which I think is what you generally want, you should look at setting up your algorithm in a different way, as suggested by #Zoffix Znet and #raiph.
No.
Seriously. Other answers seem to make too many assumptions about the implementation, none of which are tested by the spec.

PLC Object Oriented Programming - Using methods

I'm writing a program for a Schneider PLC using structured text, and I'm trying to do it using object oriented programming.
Being a newbie in PLC programming, I wrote a simple test program such a this:
okFlag:=myObject.aMethod();
IF okFlag THEN
// it's ok, go on
ELSE
// error handling
END_IF
aMethod must perform some operations, wait for the result (there is a "time-out" check to avoid deadlocks) and return TRUE or FALSE
This is what I expected during program execution
1) when the okFlag:=myObject.aMethod(); is reached, the code inside aMethod is executed until a result is returned. When I say "executed" I mean that in the next scan cycle the execution of aMethodcontinues from the point it had reached before.
2) the result of method calling is checked and the main flow of the program is executed
and this is what happens:
1) aMethod is executed but the program flow continues. That is, when it reaches the end of aMethod a value it's returned, even if the events that aMethod should wait for are still executing.
2) on the next cycle, aMethod is called again and restarts from the beginning
This is the first solution I found:
VAR_STATIC
imBusy: BOOL
END_VAR
METHOD aMethod: INT;
IF NOT(imBusy) THEN
imBusy:=FALSE;
aMethod:=-1; // result of method while in progress
ELSE
aMethod:=-1;
<rest of code. If everything is ok, the result is 0, otherwise is 1>
END_IF
imBusy:=aMethod<0;
and the main program:
CASE (myObject.aMethod()) OF
0: // it's ok, go on
1: // error handling
ELSE
// still executing...
END_CASE
and this seems to work, but I don't know if it's the right approach.
There are some libraries from Schneider which use methods that return boolean and seem to work as I expected in my program. That is: when the cycle reaches the call to method for the first time the program flow is "deviated" somehow so that in the next cycle it enters again the method until it's finished. It's there a way to have this behaviour ?
generally OOP isn't the approach that people would take when using IEC61131 languages. Your best bet is probably to implement your code as a state machine. I've used this approach in the past as a way of simplifying a complex sequence so that it is easier for plant maintainers to interpret.
Typically what I would recommend if you are going to take this approach is to try to segregate your state machine itself from your working code; you can implement a state machine of X steps, and then have your working code reference the statemachine step.
A simple example might look like:
stepNo := 0;
IF (start AND stepNo = 0) THEN
StepNo = 1;
END_IF;
(* there's a shortcut unity operation for resetting this array to zeroes which is faster, but I can't remember it off the top of my head... *)
ActiveStepArray := BlankStepArray;
IF stepNo > 0 THEN
IF StepComplete[stepNo] THEN
stepNo := stepNo +1;
END_IF;
ActiveStepArray[stepNo] := true;
END_IF;
Then in other code sections you can put...
IF ActiveStep[1] THEN
(* Do something *)
StepComplete[1] := true;
END_IF;
IF ActiveStep[2] THEN
(* Do Something *)
StepComplete[2] := true;
END_IF;
(* etc *)
The nice thing about this approach is that you can actually put all of the state machine code (including jumps, resets etc) into a DFB, test it and then shelve it, and then just use the active step, step complete, and any other inputs you require.
Your code is still always going to execute an entire section of logic, but if you really want to avoid that then you'll have to use a lot of IF statements, which will impede readability.
Hope that helps.
Why not use SFC it makes your live easier in many cases, since it is state machine language itself. Do subprogram, wait condition do another .. rince and repeat. :)
Don't hang just for ST, the other IEC languages are better in some other tasks and keep thing as clear as possible. There should be not so much "this is my cake" mentality on the industrial PLC programming circles as it is on the many other programming fields, since application timeline can be 40 years and you left the firm 20 years ago to better job and programs are almost always location/customer or atleast hardware specific.
http://www.automation.com/pdf_articles/IEC_Programming_Thayer_L.pdf

What's the point of using "while (true) {...}"?

Why do some people use while(true){} blocks in their code? How does it work?
It's an infinite loop. At each iteration, the condition will be evaluated. Since the condition is true, which is always... true... the loop will run forever. Exiting the loop is done by checking something inside the loop, and then breaking if necessary.
By placing the break check inside the loop, instead of using it as the condition, this can make it more clear that you're expecting this to run until some event occurs.
A common scenario where this is used is in games; you want to keep processing the action and rendering frames until the game is quit.
It's just a loop that never ends on its own, known as an infinite-loop. (Often times, that's a bad thing.)
When it's empty, it serves to halt the program indefinitely*; otherwise there's typically some condition in the loop that, when true, breaks the loop:
while (true)
{
// ...
if (stopLoop)
break;
// ...
}
This is often cleaner than an auxiliary flag:
bool run = true;
while (run)
{
// ...
if (stopLoop)
{
run = false;
continue; // jump to top
}
// ...
}
Also note some will recommend for (;;) instead, for various reasons. (Namely, it might get rid of a warning akin to "conditional expression is always true".)
*In most languages.
Rather than stuff all possible conditions in the while statement,
// Always tests all conditions in loop header:
while( (condition1 && condition2) || condition3 || conditionN_etc ) {
// logic...
if (notable_condition)
continue; // skip remainder, go direct to evaluation portion of loop
// more logic
// maybe more notable conditions use keyword: continue
}
Some programmers might argue it's better to put the conditions throughough the logic, (i.e. not just inside the loop header) and to employ break statements to get out at appropriate places. This approach will usually negate the otherwise original conditions to determine when to leave the loop (i.e. instead of when to keep looping).
// Always tests all conditions in body of loop logic:
while(true) {
//logic...
if (!condition1 || !condition2)
break; // Break out for good.
// more logic...
if (!condition3)
break;
// even more logic ...
}
In real life it's often a more gray mixture, a combination of all these things, instead of a polarized decision to go one way or another.
Usage will depend on the complexity of the logic and the preferences of the programmer .. and maybe on the accepted answer of this thread :)
Also don't forget about do..while. The ultimate solution may use that version of the while construct to twist conditional logic to their liking.
do {
//logic with possible conditional tests and break or continue
} while (true); /* or many conditional tests */
In summary it's just nice to have options as a programmer. So don't forget to thank your compiler authors.
When Edsger W. Dijkstra was young, this was equivalent to:
Do loop initialization
label a:
Do some code
If (Loop is stoppable and End condition is met) goto label b
/* nowadays replaced by some kind of break() */
Do some more code, probably incrementing counters
go to label a
label b:
Be happy and continue
After Dijkstra decided to become Antigotoist, and convinced hordes of programmers to do so, a religious faith came upon earth and the truthiness of code was evident.
So the
Do loop initialization
While (true){
some code
If (Loop is stoppable and End condition is met) break();
Do some more code, probably incrementing counters
}
Be happy and continue
Replaced the abomination.
Not happy with that, fanatics went above and beyond. Once proved that recursion was better, clearer and more general that looping, and that variables are just a diabolic incarnation, Functional Programming, as a dream, came true:
Nest[f[.],x, forever[May God help you break]]
And so, loops recursion became really unstoppable, or at least undemonstratively stoppable.
while (the condition){do the function}
when the condition is true.. it will do the function.
so while(true)
the condition is always true
it will continue looping.
the coding will never proceed.
It's a loop that runs forever, unless there's a break statement somewhere inside the body.
The real point to have while (true) {..} is when semantics of exit conditions have no strong single preference, so its nice way to say to reader, that "well, there are actually break conditions A, B, C .., but calculations of conditions are too lengthy, so they were put into inner blocks independently in order of expected probability of appearance".
This code refers to that inside of it will run indefinitely.
i = 0
while(true)
{
i++;
}
echo i; //this code will never be reached
Unless inside of curly brackets is something like:
if (i > 100) {
break; //this will break the while loop
}
or this is another possibility how to stop while loop:
if (i > 100) {
return i;
}
It is useful to use during some testing. Or during casual coding. Or, like another answer is pointing out, in videogames.
But what I consider as bad practice is using it in production code.
For example, during debugging I want to know immediately what needs to be done in order to stop while. I don't want to search in the function for some hidden break or return.
Or the programmer can easily forget to add it there and data in a database can be affected before the code is stopped by other manners.
So ideal would be something like this:
i = 0
while(i < 100)
{
i++;
}
echo i; //this code will be reached in this scenario