Multi-Threading and fork

Source: Internet
Author: User
Tags data structures mutex

Turn from: http://blog.csdn.net/anxuegang/article/details/6658472


Preface:The EXCE call does not create a new process, so the process ID does not change, and exec simply replaces the body, data, heap, and stack segments of the current process with a completely new program .

The

multithreaded application is not allowed to use fork: why ...
C + + programming code 3

Guideline 3: Multithreaded programs are not allowed to use fork

in multithreaded programs, "The presence of threads outside of itself" next use fork, can cause a variety of problems. A more typical example is that a fork subprocess may deadlock . Please do not fork the subprocess in a multithreaded program without grasping the cause of the problem. What problems can

cause?

Let's take a look at the example. The chances of a deadlock are high when you invoke doit () at the beginning of the execution of a subprocess by executing the following code.

void* doit (void*) {
    static pthread_mutex_t mutex = Pthread_mutex_initializer;
    Pthread_mutex_lock (&mutex);
    struct Timespec ts = {0}; nanosleep (&ts, 0);//10 seconds bed る
     & nbsp;                                                //Sleep 10 sec
    pthread_mutex_ Unlock (&mutex);
    return 0;
}

int main (void) {
pthread_t T;

Pthread_create (&t, 0, doit, 0); Make and start a child thread
if (fork () = = 0) {
Child processes
At the moment the child process is created, the parent's subprocess is more in the execution of the Nanosleep
Doit (0);

return 0;
}
Pthread_join (t, 0); //
Wait for child thread to end
}


The following are the reasons for the deadlock:
Generally, fork do the following things
1. The memory data of the parent process is copied intact to the child process
2. Child processes are generated in a single thread state


In the memory area,the memory of the static variable mutex is copied into the child process .andEven if there are multiple threads in the parent process,but they're not going to be inherited into the subprocess.. The two characteristics of fork are the cause of the deadlock.
Translator Note: A detailed explanation of the causes of deadlocks---
1. The doit () of the line Chengri is executed first.
2. When the doit is executed, the mutex variable mutex is added to the lock.
3. The contents of the mutex variable are copied to the fork process(prior to this, the contents of the mutex variable had been overwritten by the thread to the lock state).
4. When the child process calls doit again, it is found to be locked when the mutex is locked, so it waits until the process that owns the mutex releases it (no one actually owns the mutex lock).
5.The thread's doit execution will release its own mutex, but it is already two memory in the mutex and the subprocess. So even releasing a mutex lock does not affect the mutex in the process.

For example, try to consider the following execution process to see why it is *3 to accidentally use fork in the multithreaded program above.
1. In the parent process before fork, threads 1 and 2 are started
2. Thread 1 calls the doit function
3. The doit function locks its own mutex
4. Thread 1 performs Nanosleep function sleeps 10 seconds
5. Here program processing switches to thread 2
6. Thread 2 calls the fork function
7. Generating child processes
8. At this point, the doit function of the subprocess is in a "locked state", and the unlocked thread does not exist in the child process.
9. Processing of child processes begins
10. Child process Call doit function
11. The child process locks the mutex that is already locked and then causes a deadlock

Like the doit function here, a function that causes problems in multithreading because of fork, we call it the "Fork-unsafe function". Conversely, a function that does not cause a problem is called the "Fork-safe function." Although in some commercial UNIX, the functions provided by the OS ( System calls, there are Fork-safety records in the document, but in Linux (GLIBC) of course! There are no special rules in POSIX, so those functions are fork-safe and almost impossible to discriminate. If you don't understand, It would be better to consider it as a unsafe. (2004/9/12 Worm) Wolfram Gloger said that calling an asynchronous signal security function is a specification, so try to investigate, in pthread_atforkの this place has "in the meantime*5, only a short list of Async-signal-safe Library routines are promised to be available. " In that case, it's like this.

In any case, the malloc function is a typical example of maintaining an intrinsic mutex, which is usually fork-unsafe. Functions that depend on the malloc function have many, such as printf functions, that also become fork-unsafe.

So far, it's been dangerous to write about Thread+fork, but there's a special case that needs to be told. "Fork call exec immediately after the occasion, is as a special column will not cause problems”. What's the reason ...?The exec function * 61 is invoked, and the "Memory data" of the process is temporarily reset to a very beautiful state.therefore, even in the multithreaded state of the process, fork not immediately call all the dangerous functions, just call the EXEC function, the child process will not produce any error action.However, please note that the word "immediately" is used here. Even if exec just calls one back to printf ("I ' m child process"), there is a risk of deadlock.
Translator Note: When the command specified in the EXEC function is executed, the memory image of the command overwrites the memory space of the parent process. Therefore, any data in the parent process will no longer exist.

The understanding of this blog: View the previous process creation, after the child process is created, it is copied at write time, which is the same copy as the parent process when the child process was created, and when the Exce, the old address space is discarded, and the memory of the new EXEC command overwrites the memory space of the process. So the state of the lock doesn't matter.
How to avoid disaster?
In order to use fork safely in multithreaded programs, is there a way to circumvent deadlock problems? Try to think of a few.

Dodge Method 1: When doing a fork, let the other thread terminate completely before it.
It is not a problem to have other threads completely terminate before fork. But this is only possible. Also, because of some reasons and other threads can not end the execution of the fork, it will be some difficult to resolve problems of the problem.

call exec function immediately after evading method 2:fork in child process

(2004/9/11 worm something I forgot to write)
Do not use the Circumvention Method 1, after fork not call any function (printf, etc.) immediately call the EXECL, EXEC series functions. If you don't use "no exec on the fork" in the program, this should be the actual way to avoid it.
Translator Note: The author's meaning may be that the original child process should be done to write a separate program, compiled into executable program by the EXEC function to invoke.

Circumvent Method 3: "Other threads", do not do fork-unsafe processing
In addition to calling fork threads, all other threads do not do fork-unsafe processing. In order to increase the speed of the numerical calculation and use the thread of the occasion *7, this may be fork-safe processing, But that's not the case in a typical application. Even if the functions are fork-safe, it is not easy to do. Fork-safe functions must be asynchronous signaling security functions, and they can be counted. So, Malloc/new, printf These functions are not available.
Workaround 4: Use the Pthread_atfork function to invoke a prepared callback function before the fork is about to be called. Apue describes it in detail .
Using the Pthread_atfork function, the prepared callback function is invoked before the fork, in which the memory data for the purge process is negotiated. But about the functions provided by the OS (example: malloc), There is no way to clear it in the callback function. Because the data structures used in the malloc are invisible to the outside. Therefore, the Pthread_atfork function has little practical value.
Dodge Method 5: In multithreaded programs, do not use fork
is not to use the fork method. That is, to replace the fork with Pthread_create. This is a more practical way to circumvent 21, which is worth recommending.

* 1: System calls to generate child processes
* 2: Global variables and static variables within functions
* 3: If you are using Linux, it is better to view the man manual for the Pthread_atfork function. There are some explanations for these processes.
*4:solaris and HP-UX etc.
* 5: This time from fork to exec execution
*6:≒EXECVE system Call
* 7: Just doing four calculus is fork-safe.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.