Weird behaviour using fork(); - c

I have this tiny program in C
main(int argc, char **argv)
{
forkit(4);
}
void forkit(int n)
{
if(n > 0)
{
fork();
printf("%d \n", n);
forkit(n-1);
}
}
which prints
4 4 3 3 3 3 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
30 numbers, all in new lines. However, if I remove the \n in the printf statement it prints this:
4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1
Without new line it gives 64 numbers.
How is such a small change giving such different results?

Very good question, there is something subtle going on.
What's happening is that printf's output is line buffered and flushed at newlines.
All by itself, that doesn't affect the output of most programs, just the speed.
But when you fork, buffered I/O that hasn't yet been output is now present in both children. With the newline in that output has already happened so it is no longer pending in the child.
That's the explanation. If it isn't clear, another way to phrase it is: without the newline, the pending output is multiplied by the number of future children in the process tree. With the newline, it's just output that happened in the past and the program works like you expect it to.
Note that the output eventually gets flushed even without the newline, but it happens when the program calls exit(3). By then, it has already forked and passed on it's pending (i.e., buffered) output.
By the way, if you redirect the output to a file, it will be block buffered and you will probably see similar results (except for the newlines) in both cases.

Related

what is minimum number of operations required to sort an array if:-

In each operation we can either push an element to the end of the array or at the beginning of it
for example an array 3 2 5 1 4 6 would take 4 steps.
after first operation 2 3 5 1 4 6
after second operation 1 2 3 5 4 6
after third operation 2 3 1 4 6 5
after fourth operation 1 2 3 4 5 6
I think in the best case, the array is already sorted - 0 operations needed.
In the worst case, its sorted already, but in the opposite order (eg 6 5 4 3 2 1), you gonna need number of elements-1 operations.

Creating multidimensional shifting array using a vectorize approach instead of FOR loop

I can "Vectorize" the circshift command but I'm having trouble adding dimensions to it.
See code below with working FOR loop that I'm trying to vectorize using dimensions
clear all,clf reset,tic,clc , close all
function [outMat] = vectcircshift(vectToShift,shiftVector)
%This function generates a matrix where each row is a circshift of the
%original vector from the specified interval in the shiftVector;
%
%Inputs
%vectToShift: is the original vector you want to circshift multiple times
%shiftVector: is the vector of the circshift sizes;
%
%Outputs
%outMat: is a matrix were every row is circshift by the amount in the
% shiftVector
[n,m]=size(vectToShift);
if n>m
inds=(1:n)';
i=toeplitz(flipud(inds),circshift(inds,[1 0]));
outMat=vectToShift(i(shiftVector,:));
outMat=circshift(outMat,[0,-1]); %shift to include original signal first
else
inds=1:m;
i=toeplitz(fliplr(inds),circshift(inds,[0 1]));
outMat=vectToShift(i(shiftVector,:));
outMat=circshift(outMat,[0,-1]); %shift to include original signal first
end
end
%%----Working FOR LOOP below I'm trying to vectorize.
ndim=0;
ndim_tot=[1:3] %total dimensions
for ndim=1:length(ndim_tot)
ndim=ndim+0
if ndim==1
array_sort(ndim,:)=circshift(ndim_tot,[0 ndim-1]) %start at row of sort array
else
array_sort(ndim,:)=circshift(ndim_tot,[0 mod(-ndim,length(ndim_tot))+1]) %next start of row of sort array
endif
array_sort= array_sort(ndim,:)
array_dim(:,:,ndim)=vectcircshift([1:5],array_sort)
endfor
I tired the syntax below but that logic won't work.
ndim_tot=[1:3]; %number of dimensions
array_dim2(:,:,ndim_tot)=vectcircshift([1:5],[1:3])
I get an error nonconformant arguments(op1 is 0x0x1, op2 is 3x5)
My goal is to create a multidimensional array that circshifts a signal / array and also creates and shifts it in multiple dimensions.
Example: of what the multidimensional array would look like
if I start with a signal / array a1=[1 2 3 4 5]
I'm trying to have it create.
array_dim(:,:,1)=
[
1 2 3 4 5
5 1 2 3 4
4 5 1 2 3
]
array_dim(:,:,2)=
[
5 1 2 3 4
4 5 1 2 3
1 2 3 4 5
]
array_dim(:,:,3)=
[
4 5 1 2 3
1 2 3 4 5
5 1 2 3 4
]
Please note: the the numbers won't be sequential I just used it as an example to help explain things a little easier.
PS: I'm using Octave 4.2.2
Not clear why you are shifting in mod 3, but here is a loop assignment using shift
a1=[1 2 3 4 5];
array_dim=zeros(3,5,3);
for i=0:2
array_dim(:,:,i+1)=[shift(a1,i);
shift(a1,mod(i+1,3));
shift(a1,mod(i+2,3))];
endfor
array_dim
and the output fits your example
array_dim =
ans(:,:,1) =
1 2 3 4 5
5 1 2 3 4
4 5 1 2 3
ans(:,:,2) =
5 1 2 3 4
4 5 1 2 3
1 2 3 4 5
ans(:,:,3) =
4 5 1 2 3
1 2 3 4 5
5 1 2 3 4

How do I plot animation using gnuplot version 4.2?

I have two data sets in a single file called "numbers.dat" with three columns. First data set corresponds to time t=0 and it has two sub sets (1 and 2 below, separated by a single new line). Second set corresponds to time t=1 also with two similar sub sets (3 and 4).
I need to plot an animated version for t=0 for 2 seconds (say) and then for t=1 for 2 seconds.
I can use two line spacing between t=0 and t=1 or I can also write them in separate files, if required.
My data file "numbers.dat" looks like this:
1 1 1
1 1 1
1 1 1
1 1 1
2 2 2
2 2 2
2 2 2
2 2 2
3 3 3
3 3 3
3 3 3
3 3 3
4 4 4
4 4 4
4 4 4
4 4 4
My gnuplot version is 4.2. How do I get the animation?

Array processing, shapes

I have a square 2d array of values, where each row is identical, and where each element of row is one bigger than the last. For example:
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
I want to filter them, such that I can make a diamond as such:
1
1 2 3
1 2 3 4 5
1 2 3 4 5 6 7
1 2 3 4 5
1 2 3
1
Notice how the first part of the array is used, no matter how many elements are to be printed on that line. Also, spacing doesn't matter. I spaced them to show the diamond.
I know how to filter the top right "chunk" out, using j-i<(j/2). This will convert the original square into:
1
1 2 3
1 2 3 4 5
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
How can I get the bottom right "chunk" to filter out also? What additional condition can I impose on the values?
Presuming you have found out and stored the length of the "side" of the square already then you could use something like below. However, if your square has an even length then it will not work (can't produce a diamond in this way from an even side length square).
The following is pseudo-code so you will need to adapt it for your language. I've also used 0-indexed arrays and presumed square is a 2D array.
for (i=0, i<length, i++)
{
for (j=0, j<Length, j++)
{
if (i < length/2)
{
if (j < length/2 AND j <= i)
print square[i][j]
}
}
else
{
if (j < length/2 AND j <= (length - i))
{
print square[i][j]
}
}
}
print newline
}

How to use random_shuffle in a for loop to achieve different different shuffled arrays?

i want to have 10 different shuffled form of an array...but random_shuffle produce the same sequence for 10 times...
and my code is...
for(k=0;k<10;k++) {
for (l=0; l<SIZE;l++)
a[l]=l+1;
srand(time(0));
random_shuffle(a,a+SIZE); //getting the shuffled sequence
for(;i<10;i++) {
for(j=0;j<5;j++) {
rcusseq[i][j]=a[m++]; //storing the sequence in a 2d array
printf("%d\t",rcusseq[i][j]);
}
m=0;
printf("\n");
}
}
OUTPUT
5 4 2 1 3
5 4 2 1 3
5 4 2 1 3
5 4 2 1 3
5 4 2 1 3
5 4 2 1 3
5 4 2 1 3
5 4 2 1 3
5 4 2 1 3
5 4 2 1 3
Press any key to continue
You're reinitializing the random number generator each time, as your code is quick enough to run within 1 second, you get the same seed every time.
Move srand(time(0));out of the loop.
Only call srand() once in a program, e.g. at the beginning of main().

Resources