概述
Threads and fork
When a thread calls fork, a copy of the entire process address space is made for the child. Recall the discussion of copy-on-write in Section 8.3. The child is an entirely different process from the parent, and as long as neither one makes changes to its memory contents, copies of the memory pages can be shared between parent and child.
#include <pthread.h>
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
The parent and the child end up unlocking duplicate locks stored in different memory locations, as if the following sequence of events occurred:
1.The parent acquired all its locks.
2.The child acquired all its locks.
3.The parent released its locks.
4.The child released its locks.
We can call pthread_atfork multiple times to install more than one set of fork handlers.
For example, assume that module A calls functions from module B and that each module has its own set of locks. If the locking hierarchy is A before B, module B must install its fork handlers before module A. When the parent calls fork, the following steps are taken, assuming that the child process runs before the parent:
1.The prepare fork handler from module A is called to acquire all of module A’s locks.
2.The prepare fork handler from module B is called to acquire all of module B’s locks.
3.A child process is created.
4.The child fork handler from module B is called to release all of module B’s locks in the child process.
5.The child fork handler from module A is called to release all of module A’s locks in the child process.
6.The fork function returns to the child.
7.The parent fork handler from module B is called to release all of module B’s locks in the parent process.
8.The parent fork handler from module A is called to release all of module A’s locks in the parent process.
9.The fork function returns to the parent.
#include "apue.h"
#include <pthread.h>
pthread_mutex_t lock1=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock2=PTHREAD_MUTEX_INITIALIZER;
void prepare(void)
{
int err;
printf("preparing locks...n");
if((err=pthread_mutex_lock(&lock1))!=0)
err_count(err,"can't lock lock1 in prepare handler");
if((err=pthread_mutex_lock(&lock2))!=0)
err_count(err,"can't lock lock2 in prepare handler");
}
vid parent(void)
{
int err;
printf("parent unlocking locks...n");
if((err=pthread_mutex_unlock(&lock1))!=0)
err_count(err,"can't unlock lock1 in parent handler");
if((err=pthread_mutex_unlock(&lock2))!=0)
err_count(err,"can't unlock lock2 in parent handler");
}
void child(void)
{
int err;
printf("child unlocking locks...n");
if((err=pthread_mutex_unlock(&lock1))!=0)
err_count(err,"can't unlock lock1 in child handler");
if((err=pthread_mutex_unlock(&lock2))!=0)
err_count(err,"can't unlock lock2 in child handler");
}
void *thr_fn(void *arg)
{
printf("thread started...n");
pause();
return 0;
}
int main(void)
{
int err;
pid_t pid;
pthread_t tid;
if((err=pthread_atfork(prepare, parent,child))!=0)
err_exit(err, "can't install fork handlers");
if((err=pthread_creaete(&tid, NULL,thr_fn,0))!=0)
err_exit(err,"can't create thread");
sleep(2);
printf("parent about to fork...n");
if((pid=fork())<0)
err_quit("fork failed");
else if(pid==0)
printf("child returned from forkn");
else
printf("parent return from forkn");
return 0;
}
pthread_atfork example
最后
以上就是寒冷花生为你收集整理的Advanced Programming in UNIX Environment Episode 65的全部内容,希望文章能够帮你解决Advanced Programming in UNIX Environment Episode 65所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复