I'm afraid I have to take out a bit of length so that my question can be understood exactly. I know that forking can cause some problems, especially if you mix it with threads. One nasty problem I encountered was that a thread was cloned by a fork in the middle of a "localtime"-call, which made it impossible to continue working in the forked process because "localtime" (not stateless) remained in a low-level lock forever. Furthermore, there were problems with the C library libmysql, for example, when an open connection was forked and then closed in the forked process via mysql_close(). Since the forked process is a long-lived process and I cannot do without threads, I have decided, in order to avoid as many such problems as possible, to outsource the business-logic-routine of the forked process as a real executable binary and execute it in the forked process via "execv". Before execv(), all file descriptors (FD's) are closed.
What do I still have to consider here now in this new scenario B regarding low-level-locks, threads, mysql, ... ? Is it always safe to NOT pay attention to anything here now in the forked process?
OLD Scenario A:
(Compare: Forking a process with threads containing sockets in C++)
Process P1 with
- Open receiving Socket S1 at Port 6610
- Open SQL-Connection SQL1
- Thread T1 with
- Open SQL-Connection SQL2
- Socket-Connection S2
Prozess P1 should be forked to P2 and P2
needs the sql-connection too. T1 is not used by P2.
Socket S1 is also not used by P2.
Before fork():
- mysql_close() at SQL1 of P1
- Waiting to bring T1 in a state, where it is 100% idle and not
calling any calls like "localtime". SQL2 remains open.
Then after fork() in P1 (parent):
- Reopen mysql connection SQL1
- Continue processing in T1
Then after fork() in P2 (child):
- Reopen mysql connection SQL1
- Close socket S1
- T1 is "dead" in a controlled 100% idle state, without blocking anything.
- Doing the business logic
NEW Scenario B:
Process P1 with
- Open receiving Socket S1 at Port 6610
- Open SQL-Connection SQL1
- Thread T1 with
- Open SQL-Connection SQL2
- Socket-Connection S2
Prozess P1 should be forked to P2 and P2
needs the sql-connection too. T1 is not used by P2.
Socket S1 is also not used by P2.
Before fork():
- Consider nothing
Then after fork() in P2 (child):
- Closing ALL FD's (except STDOUT/STDERR) with close()
- execv -> replaces all memory with new process image I1
- I1 is doing a new sql-connection
- I1 Doing the business logic
Question 1:
Scenario B here seems to be the better (easier) way for me, because I have not not deal
with states of other threads (right?) because the process image is replacing the whole memory and overwriting all memory-states like mutex/locks.
But what happens here with os-ressources, which survive the execv() in the new process
like descriptors of sockets etc? More concrete, if I close all FD's with close() in the child P2, will the (open) mysql-connections SQL1 & SQL2 (also using FDs for its internal sockets, right?) be affected here? Will only be the ref-Count
decremented or are the sql-connections in P1 endangered? Same for S1/S2? All safe here?
Question 2:
What happens ins Scenario A with SQL2 and S2 in P2 because they remain completely untouched for a long time (days).
Are they possibly blocking the freeing of resources in P1 because the descriptor refcount is not counting down? Apart from that, are there any other problems here? If P2 is terminating without calling mysql_close(), will the sql-connection survice in p1?