bash and c - 2 processes in concurrency to write a file
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
bash and c - 2 processes in concurrency to write a file
Hi,
I made a C program, it forks 2 processes and each one of them uses
Code:
system()
to call 2 scripts (script1.sh and script2.sh), what I want to do is let them write in a file (output.txt) in parallel but in different moments.
For now my script1.sh (from process P1) write in the file for first, and then script2.sh (from process P2) write in the same file, but I need them to write in this way:
Code:
time 1: P1 writes 2 words in "output.txt"
time 2: P2 wirtes 3 words in "output.txt"
time 3: P1 writes 1 word in "output.txt"
time 4: P2 writes 6 words in "output.txt"
etc...
I know that
Code:
system()
function is synchronous, but I succeeded in making it asynchronous using
Code:
system("script1.sh &")
The problem is that I don't know how to do that, because if P1 calls script1.sh with "&" it executes during P2 without pauses, so that's not what I want.
I also know how to stop P1 using
Code:
pkill -f "script1.sh
, so maybe it helps I don't know.
How can I reach that aim?
Thanks
edited at the bottom:
Last edited by Hoxygen232; 02-05-2013 at 03:17 PM.
ok and from the c programm do I have to call this 2 scripts with system("name.sh") or system("name.sh &")?
The problem is that if I call these 2 scripts with
Code:
system("script1.sh &")
system("script2.sh &")
I don't have a way to say to C program when to stop them, I mean that I tried to call them in that way, but in my program every script is called by a process (fork), so if child1 calls script1 and script2:
Code:
system("script1.sh &")
system("script2.sh &")
there is no way to terminate them just during child1 is alive, infact I wrote:
Code:
printf("\nSCRIPT called by child1:\n");
system("bash script1.sh &");
system("bash script2.sh &");
sleep(2);
child1_termination=0;
exit(child1_termination);
but it doesn't work because the keep running also after child1 has finished and obviously my program does other things after child1 like forking more childs, so it's not good.
Last edited by Hoxygen232; 02-05-2013 at 12:21 PM.
This is what I need: I made a C program, it forks 2 childs: P1, P2 I also made some bash scripts.
I need P1 to run script1.sh, and P2 to run script2.sh. At the moment I'm using the function
Code:
system("script_name.sh")
or
Code:
system("script_name &")
to make it asynchronous, I don't know if it's the right choice because for now they don't work as I want. Btw:
script1.sh does this:
Code:
# it search a word in a dictionary and write in a file the exact line in which that
# word is in the dictionary, i.e. word="a" is in position "1" so
# it will write "1" in the first line of file.
while read line;
do
sleep 1
TRASFORMATA=$( echo "$line" | tr "[:upper:]" "[:lower:]" | sed -e 's/ //g' )
echo "WORDS TO SEARCH IN DICTIONARY : $TRASFORMATA:"
WORD=$( fgrep -w -i "$TRASFORMATA" "$dictfile" ) # got from dictionary
echo $WORD
if [ -z "$WORD" ] ## if it's not in dictionary
then
echo "$WORD not found!"
echo
else
echo "Word and relative line found.........."
##### if found, it write the relative line to a file #####
LINE1=$( fgrep -w -n "$WORD" "$dictfile" | sed s/:$WORD//g )
echo "$LINE1" >> "$FILE_OUTPUT"
fi
done < "$FILE_INPUT"
script2.sh does this:
Code:
# delete lines starting with letter 'z' FROM SAME FILE THAT USES script1.sh
sleep 1
while true;
do
sleep 2
echo "DELETING WORDS "
sed -i '/^z/d' "$FILE_OUTPUT"
done
They work on the SAME file (.txt). What I want is to run them at the same moment and they have to work by turns, I mean that after P! has read the first line with its script1, P2 has to run its script2, same with second line, third line, etc...
How can I do this from C program? The important thing is that every process runs one script, and these scripts has to be executed in parallel alternating them. In this way I reach my aim that is to let 2 processes to produce one output together in order to allowa one third process to read that output and work on it!
that's great and I think that it's what I need, the problem is that I don't know those function and I don't know how to put them together :/
For example I don't know about sharing pipes from bash to C or from C to bash (maybe I did'nt understand your answer).
Btw thanks because that's what I need to do.
Maybe I could give you my code to understand how to do those steps on my code:
Code:
switch(child1=fork()) {
case -1: /// father
perror("FORK failed");
uscita=1;
exit(uscita);
case 0: /// child1
sleep(1);
printf("child 1: \n");
sleep(1);
printf("\nSCRIPT called by child1:\n");
system("bash script1.sh");
printf("\n");
sleep(2);
child1_termination=0;
exit(child1_termination);
default: /// child1's father
printf("father: I have created child1.\n");
printf("father: I'm waiting child1 termination before fork child2\n");
wait (&child1_termination); // waiting for child1
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/*Fork to create child2*/
switch(child2=fork()) {
case -1: /// father
perror("second FORK failed");
uscita=1;
exit(uscita);
case 0: /// child2
printf("child2: child2\n");
sleep(2);
printf("\nSCRIPT called by child2:\n");
system("bash script2.sh");
printf("\n");
sleep(2);
child2_termination=0;
exit(child2_termination);
default: /// father
printf("father: I have created child2.\n");
printf("father: I'm waiting child2 termination before fork child3\n");
wait (&child2_termination); //waiting for child2
printf("father: Child2 has terminated running\n");
Last edited by Hoxygen232; 02-05-2013 at 04:21 PM.
that's great and I think that it's what I need, the problem is that I don't know those function and I don't know how to put them together :/
There's man page for each of the function.
Quote:
Originally Posted by Hoxygen232
For example I don't know about sharing pipes from bash to C or from C to bash (maybe I did'nt understand your answer).
Shell script does not need to be aware of the pipes at all. Since the child will redirect the proper pipe end to its standard input/output (depending which scenario you need), the script will just read/write data to its standard input/output.
thanks for your replies, the problem is that understanding this from zero is very difficult for me and I'm not english :/
Could you please make an example on my code just to understand something. the are also my scripts up here in order to see what they do.
pipe man page has a nice example of how to use pipe, so for starters compile it and start playing with it.
First, change it so that child uses execl() to call the script instead of doing anything by itself. Example usage may be found in execve man page. For your use case, it seems that you'll be interested in calling execl("./script1.sh", "./script1.sh", (char *)0);.
Second, change it so that instead of writing argument to the pipe it copies standard input to the process. With that, you can further change it so that it prints some message after writing each line.
If you need to read output from the script and not write to it, than reverse the direction.
With that, it should be not that hard to create another child and write/read data to/from one and than the other.
I have read this thread several times, but I'm still confused.
1) What are you trying to do in the first place?
2) Why do you need one C program and two shell scripts to do it?
If I understand it correctly (which I most likely don't), you have one input file and two scripts, such that
but you want to write their output into the same file, and synchronized so that one line is written by script1, then another one by script2, and the next one by script1, and so on.
This seems pretty strange to me. I mean in one step, you construct a loop in a script, only to have to break it into pieces further up in your program? First, why don't you just put the loop where it has a point
Code:
,--> [ script1 ( one line per call ) ] -.
[ INPUTFILE ] ----> [ program ( LOOP ) ] -+ +--> [ OUTPUTFILE ]
`--> [ script2 ( one line per call ) ] -'
Or, just write a single program/script that does all the work.
Also, reading your code from the post #4, please note that you cannot have one process write into a file and sed -i with it in the same time and expect to get anything reasonable.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.