`

《APUE》:线程和fork(父子进程锁)

阅读更多
《Unix环境高级编程》这本书附带了许多短小精美的小程序,我在阅读此书的时候,将书上的代码按照自己的理解重写了一遍(大部分是抄书上的),加深一下自己的理解(纯看书太困了,呵呵)。此例子在Ubuntu10.04上测试通过。

程序简介:多线程的进程通过fork函数创建子进程时,如果要清除各种锁的状态,可以通过调用pthread_atfork函数建立fork处理程序。

//《APUE》程序12-7:pthread_atfork实例  
#include <stdio.h>  
#include <stdlib.h>  
#include <unistd.h>  
#include <signal.h>  
#include <pthread.h>  
 
pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER; 
pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER; 
 
void prepare(void) 

    printf("preparing locks...\n"); 
    pthread_mutex_lock(&lock1); 
    pthread_mutex_lock(&lock2); 

 
void parent(void) 

    printf("parent unlocking locks...\n"); 
    pthread_mutex_unlock(&lock1); 
    pthread_mutex_unlock(&lock2); 

 
void child(void) 

    printf("child unlocking locks...\n"); 
    pthread_mutex_unlock(&lock1); 
    pthread_mutex_unlock(&lock2); 

 
void *thr_fn(void *fn) 

    printf("thread started...\n"); 
    pause(); 
    return 0; 

 
int main(void) 

    pid_t pid; 
    pthread_t tid; 
    //BSD系统和MAC OS系统不支持pthread_atfork  
#if defined(BSD) || defined(MACOS)  
    printf("pthread_atfork is unsupported\n"); 
#else  
    //见注解2  
    pthread_atfork(prepare, parent, child); 
    pthread_create(&tid, NULL, thr_fn, NULL); 
    sleep(2); 
    printf("parent about to fork...\n"); 
 
    pid = fork(); 
    if( 0 == pid ) 
        printf("child returned from fork\n"); 
    else 
        printf("parent returned from fork\n"); 
#endif  
 
    return 0; 

运行示例(红色字体的为输入):

www.linuxidc.com @ubuntu:~/code$ gcc temp.c -lpthread -o temp
www.linuxidc.com @ubuntu:~/code$ ./temp

thread started...
parent about to fork...
preparing locks...
parent unlocking locks...
parent returned from fork
child unlocking locks...
child returned from fork


注解:
1:父进程通过fork创建了子进程。子进程不但继承了父进程整个地址空间的副本,也继承了所有的互斥量,读写锁和条件变量的状态,如果父进程包含多个线程,子进程在fork返回之后,如果不是紧接着使用exec的话,就要清理锁状态。
2:pthread_atfork最多可以安装三个帮助清理锁的函数。prepare函数将在fork创建子进程之前被调用,通常可以用来获取进程中的所有锁;parent在fork创建子进程后返回前在父进程中被调用,可以用来释放父进程中的锁;child在fork创建子进程后fork返回前在子进程中被调用,可以用来释放子进程中的锁。给这三个参数传递NULL,表示不调用该函数。
分享到:
评论
Global site tag (gtag.js) - Google Analytics