Linux Advance--线程和fork
来源:互联网 发布:医疗大数据公司排名 编辑:程序博客网 时间:2024/04/30 08:32
当线程调用 fork 时,就为子进程创建了整个进程地址空间的副本。子进程通过继承整个地址空间的副本,也从父进程那里继承了所有互斥量、读写锁和条件变量的状态。如果父进程包含多个进程,子进程在 fork 返回之后,如果紧接着不是马上调用 exec 的话,就需要清理锁状态。
要清除锁状态,可以通过调用pthread_atfork 函数建立 fork 处理程序。
#include <pthread.h>int pthread_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void));
父进程和子进程对在不同内存位置的重复的锁都进行了解锁操作,就好像出现了下列的事件序列:
1、父进程获得所有的锁
2、子进程获得所有的锁
3、父进程释放它的锁
4、子进程释放它的锁
下面是例程:
#include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <string.h>#include <errno.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 *arg){printf("thread started...\n");pause();return 0;}int main(){int err;pid_t pid;pthread_t tid;#if defined(BSD) || defined(MACOS)printf("pthread_atfork is unsupported\n");#elseif ((err = pthread_atfork(prepare, parent, child)) != 0) {printf("can't install fork handlers: %s\n", strerror(err));exit(1);}err = pthread_create(&tid, 0, thr_fn, 0);if (err != 0) {printf("can't create thread: %s\n", strerror(err));exit(1);}sleep(2);printf("parent about to fork...\n");if ((pid = fork()) < 0) {printf("fork failed\n");exit(1);} else if (pid == 0)printf("child returned from fork\n");elseprintf("parent returned from fork\n");#endif // defined exit(0);}
程序中定义了两个互斥量,lock1 和 lock2,prepare fork 处理程序获取这两把锁,child fork 处理程序在子进程环境中释放锁,parent fork 处理程序在父进程中释放锁。
运行该程序得到如下输出:
可以看出,parent fork 处理程序在调用 fork 以后运行,child fork 处理程序在 fork 调用返回到子进程之前运行,parent fork 处理程序在 fork 调用返回给父进程前运行。
1 0
- Linux Advance--线程和fork
- Linux Advance--set_fl 和 clr_fl
- Linux Advance--线程清理处理函数
- Linux中进程、线程和fork()
- 线程和fork
- 线程和fork
- 线程和fork()
- 线程和fork
- [APUE] 线程和fork
- 线程和fork
- 线程和fork-
- Linux Advance--从一道题谈linux下fork的运行机制
- linux fork 和 vfork
- linux fork()和execve()
- Linux Advance--输出错误信息
- Linux Advance--守护进程
- Linux Advance--打印文件类型
- 【linux】fork() && fork() || fork()
- 简单的求和
- poj 2516 Minimum Cost(最小费用最大流 spfa算法求最短路)
- gcc 编译器中 printf i++ 和 ++i 的输出
- Romberg(龙贝格)求积公式求解数值积分时的注意事项
- 单链表的实现
- Linux Advance--线程和fork
- 1093. Count PAT's (25)
- 多线程 NSOperation
- Google Protocol Buffers介绍
- samba ubuntu下快速配置
- C++ 学习(虚基类)
- FindBugs插件的安装与使用
- SDWebImage 第三方框架
- 安卓学习知识点总结一