28

I want to launch a process from within my c program, but I don't want to wait for that program to finish. I can launch that process OK using system() but that always waits. Does anyone know of a 'non-blocking' version that will return as soon as the process has been started?

[Edit - Additional Requirement] When the original process has finished executing, the child process needs to keep on running.

1
  • 1
    I thought system() was non blocking. Commented Nov 12, 2013 at 21:33

6 Answers 6

24

One option is in your system call, do this:

 system("ls -l &"); 

the & at the end of the command line arguments forks the task you've launched.

Sign up to request clarification or add additional context in comments.

Comments

16

Why not use fork() and exec(), and simply don't call waitpid()?

For example, you could do the following:

// ... your app code goes here ... pid = fork(); if( pid < 0 ) // error out here! if( !pid && execvp( /* process name, args, etc. */ ) // error in the child proc here! // ...parent execution continues here... 

5 Comments

hmmm, doesn't seem to be working for me. I think the problem might be that my program (it's a CGI app) exists as soon as it's called execvp - will this kill off the child process? Also... the code after execvp appears to be being run twice.
Simon, can you place a code sample here? What might happens is the parent has exit as soon as child process had been forked. Have you used waitpid(chld_pid) as proposed by Mr./Ms. FreeMemory?
@Simon: if the code after execvp() appears to run twice, most likely it means that the execvp() failed and the error handling for it didn't stop things going awry (return or exit). In a CGI program, do you know what the PATH is set to? It is probably more spartan than you expected.
OK, I've read up some more about fork() and now understand the above example better and know why some of the code was being run twice. It's a bit difficult to see what's happening, but I think the forked process is being killed off when the original process exits.
@Simon: To make the child process live on, couldn't you trap SIGHUP?
9

The normal way to do it, and in fact you shouldn't really use system() anymore is popen.
This also allows you to read or write from the spawned process's stdin/out

edit: See popen2() if you need to read and write - thansk quinmars

Comments

1

You could use posix_spawnp() function. It's much similar to system() than the fork and exec* combination, but non-blocking.

Comments

0

In the end, this code appears to work. Bit of a mis-mash of the above answers:

pid = fork(); if (!pid) { system("command here &"); } exit(0); 

Not quite sure why it works, but it does what I'm after, thanks to everyone for your help

2 Comments

It works, but it's not really what you want to do. system() actually forks an instance of a shell, and passes the shell the command you want to execute. So basically, what you're doing is as follows: fork(), fork(), execl( "/bin", "sh", "command_to_run &" ). Sure, it works, but it's doing a lot more work than it ought to.
why the extra fork()? Can't you just use the system("... &"); call?
-2

How about using "timeout" command if you are looking for your command to exit after a specific time:

Ex: system("timeout 5 your command here"); // Kills the command in 5 seconds if process is not completed

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.