Ram
Ram

Reputation: 1193

forking a new process in perl on linux

I want to fork a background process from a cgi call. So that the httpd call returns immediately and rest of the stuff keeps running

This used to work all this while until we migrated to a new machine

............
## Close the http connection so that the remote client returns
close STDOUT;
close STDERR;
POSIX::setsid();
fork() && exit;
do_job();
.........

Now on the new machine , same code never executes the do_job() Perl , httpd versions are the same ( there is a minor kernel upgrade )

Now I changed the code to

..........
open(STDOUT,">/dev/null");
open(STDERR,">/dev/null");
POSIX::setsid();
fork() && exit;
do_job();
.........

This works, but I am not sure why

Upvotes: 1

Views: 1489

Answers (2)

StarPinkER
StarPinkER

Reputation: 14271

I'm not quite sure about why the first code will work. But you should always put setsid after the fork(). Pls let me know if it doesn't work after you doing this.

Every process group is in a unique session. (When the process is created, it becomes a member of the session of its parent.) By convention, the session ID of a session equals the process ID of the first member of the session, called the session leader. A process finds the ID of its session using the system call getsid().

A new session is created by

pid = setsid();

This is allowed only when the current process is not a process group leader.

Let me explain why. Assume if you are process group leader or session leader you have to understand that process group and session ids are initialized from the process id of the process creating them (and then leading them, i.e. for a session leader pid == sid and for a process group leader pid == pgid). Moreover, process groups cannot move between sessions.

That means if you are a process group leader, and creating a new session would be allowed then the sid and the pgid would get set to your pid, leaving the other processes in your old process group in a weird state: their process group leader suddenly is in a different session then they themselves might be. And that cannot be allowed, hence the EPERM returned by the kernel.

Now if you fork() once you are neither session nor process group leader anymore and hence setting your sid and pgid to your pid is safe, because there are no other processes in such group.

The following links might be helpful:

Sessions and Process Groups

The Linux Kernel: Process

Upvotes: 2

Miguel Prz
Miguel Prz

Reputation: 13792

I recommend you the use of an external queue that handles this kind of work. You can use some CPAN modules to get this funcionallity, like Queue::DBI or others, like Gearman

Upvotes: 0

Related Questions