Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I made a C program, it forks 2 processes and each one of them uses

 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:

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

 system()

function is synchronous, but I succeeded in making it asynchronous using

 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

 pkill -f "script1.sh

so maybe it helps I don't know.

How can I reach that aim? Thanks

share|improve this question
2  
you need to lock the the file while editing. Check for semaphore & mutex . –  Web-E Feb 5 '13 at 18:06
    
Suggestion: instead of doing the two system() calls sequentially and using the shell to background the scripts, use the C fork() function to split your C program into two concurrent threads. In your code you will then have the line if (fork()) system("script1.sh"); else system("script2.sh"); –  zwets Mar 21 '13 at 9:13

2 Answers 2

What you can do is an old UNIX trick, which is the fact that a file rename operation at least in a standard UNIX filesystem is atomic.

Here is what you can do:

Have a single file that is being written to, say output. The filename would take 3 different forms:

  1. "output" - the actual file
  2. "output.script1" - the filename that is meant for script 1 to write
  3. "output.script2" - filename meant for script2 to write.

Each script will have a mechanism to wait for a file and then pick it up and write to it. For example, in script 1:

script1.sh:

function check_for_file {
    local file=$1
    if [[ -f "$1" ]];then
        return 1
    else
        return 0
    fi
}

function wait_for_file {
    local file=$1
    while (( `check_for_file $file` == 0 ))
    do
        # sleep 1 second and check again
        sleep 1
    done
}

# MAIN

# pass 1:
wait_for_file "output.script1"
# got file now
echo "whatever you need to write for pass 1" >> output.script
# done with first write, pass file to second script
mv "output.script1" "output.script2"
wait_for_file

# pass 2: do what I need to do for pass 2
# ... etc

The same script mechanism can then be used for script 2. Just make sure in script 2 you rename it from script2.

Then have the following:

  1. in your C program, you can create the output file first and write whatever you need first (i.e. fopen("output", "w")). And write to it if you need. Close the file pointer.
  2. Launch the scripts in the background. (system call that you have)
  3. Rename the file "output" to "output.script1" and the script 1 will pick it up.
share|improve this answer

Maybe you can fork GNU Parallel and redirect the output to the file:

system("(echo script1.sh; echo script2.sh) | parallel > output.txt");
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.