linux threads,linuxthreads源码分析之ptfork.c(基于linuxthreads2.0.1)

/* The "atfork" stuff */

#include

#include

#include

#include "pthread.h"

#include "internals.h"

struct handler_list {

void (*handler)(void);

struct handler_list * next;

};

// 用于互斥访问链表的互斥变量

static pthread_mutex_t pthread_atfork_lock = PTHREAD_MUTEX_INITIALIZER;

// 三个链表

static struct handler_list * pthread_atfork_prepare = NULL;

static struct handler_list * pthread_atfork_parent = NULL;

static struct handler_list * pthread_atfork_child = NULL;

// 生成一个新的handler_list节点插入到list中

static void pthread_insert_list(struct handler_list ** list,

void (*handler)(void),

struct handler_list * newlist,

int at_end)

{

if (handler == NULL) return;

// 插入到最后,则先把直接指向尾节点

if (at_end) {

while(*list != NULL) list = &((*list)->next);

}

// 保存数据到新节点

newlist->handler = handler;

// *list即第一个节点的地址

newlist->next = *list;

// *list的内容修改为新节点

*list = newlist;

}

struct handler_list_block {

struct handler_list prepare, parent, child;

};

int pthread_atfork(void (*prepare)(void),

void (*parent)(void),

void (*child)(void))

{

struct handler_list_block * block =

(struct handler_list_block *) malloc(sizeof(struct handler_list_block));

if (block == NULL) return ENOMEM;

pthread_mutex_lock(&pthread_atfork_lock);

/* "prepare" handlers are called in LIFO */

// 把三个函数保存到一个节点中,如果这个节点分别插入三个handle_list队列

pthread_insert_list(&pthread_atfork_prepare, prepare, &block->prepare, 0);

/* "parent" handlers are called in FIFO */

pthread_insert_list(&pthread_atfork_parent, parent, &block->parent, 1);

/* "child" handlers are called in FIFO */

pthread_insert_list(&pthread_atfork_child, child, &block->child, 1);

pthread_mutex_unlock(&pthread_atfork_lock);

return 0;

}

// handle_list链表中每个节点的函数

static inline void pthread_call_handlers(struct handler_list * list)

{

for (/*nothing*/; list != NULL; list = list->next) (list->handler)();

}

extern int __fork(void);

// http://man7.org/linux/man-pages/man3/pthread_atfork.3.html

/*

glibc中定义了fork和__fork的关系。

weak_alias (__fork, fork)

# define weak_alias(name, aliasname) _weak_alias (name, aliasname)

# define _weak_alias(name, aliasname) \

extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)))

fork是弱符号,并且是__fork的的别名。即如果定义了fork,则会覆盖glibc中的fork。

这里就是覆盖glibc的fork,然后在调用glibc的__fork之前执行一些额外的操作。这样用户在执行fork的时候,

就会执行下面这个fork函数,从而执行glibc的__fork

*/

int fork(void)

{

int pid;

struct handler_list * prepare, * child, * parent;

pthread_mutex_lock(&pthread_atfork_lock);

prepare = pthread_atfork_prepare;

child = pthread_atfork_child;

parent = pthread_atfork_parent;

pthread_mutex_unlock(&pthread_atfork_lock);

// 调fork之前调用函数列表

pthread_call_handlers(prepare);

pid = __fork();

// 子进程

if (pid == 0) {

__pthread_reset_main_thread();

__fresetlockfiles();

pthread_call_handlers(child);

} else {

// 父进程

pthread_call_handlers(parent);

}

return pid;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值