父子进程变量虚拟内存地址相同但变量值不同
2023-04-18 15:42:33 时间
基础介绍
#include<pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <wait.h>
//global var
int g_v = 30;
int main(){
int a_v=30;//local var
static int s_v = 30;//static var
int pid = fork();
if(pid < 0){
printf("error");
}else if(pid > 0){//parent
printf("I am parent process pid is %d
",getpid());
printf("g_v:%d a_v:%d s_v:%d
",g_v,a_v,s_v);
g_v = 40;
a_v = 40;
s_v = 40;
printf("g_v : %p
a_v : %p
s_v : %p
",&g_v,&a_v,&s_v);
printf("g_v:%d a_v:%d s_v:%d
",g_v,a_v,s_v);
}else{
printf("I am son process pid is %d
",getpid());
printf("g_v:%d a_v:%d s_v:%d
",g_v,a_v,s_v);
g_v = 50;
a_v = 50;
s_v = 50;
printf("g_v : %p
a_v : %p
s_v : %p
",&g_v,&a_v,&s_v);
printf("g_v:%d a_v:%d s_v:%d
",g_v,a_v,s_v);
}
printf("out
");
printf("g_v:%d a_v:%d s_v:%d
",g_v,a_v,s_v);
return 0;
}
此处:
父进程已经将变量修改为40了,而且子进程与父进程的变量内存地址均是一样的,但是子进程打印变量任然为30.
可见:
父进程和子进程的虚拟地址空间是相同的,但是变量值确实不同。
多线程下死锁
背景
《Linux高性能服务器编程》第14章的代码
用于多进程的时候,子进程会对父进程的锁进行复制,此时很容易出现多次加锁导致死锁。代码如下:
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <wait.h>
pthread_mutex_t mutex;
void* another( void* arg )
{
printf("我是子线程,打算加锁
");
pthread_mutex_lock( &mutex );
printf("我是子线程,成功加锁 我的锁%p
",&mutex);
sleep( 5 );
printf("我是子线程,打算解锁
");
pthread_mutex_unlock( &mutex );
printf("我是子线程,成功解锁 我的锁%p
",&mutex);
}
void prepare()
{
printf("prepare加锁
");
pthread_mutex_lock( &mutex );
printf("prepare解锁
");
}
void infork()
{
printf("infork加锁
");
pthread_mutex_unlock( &mutex );
printf("infork解锁
");
}
int main()
{
pthread_mutex_init( &mutex, NULL );
pthread_t id;
pthread_create( &id, NULL, another, NULL );
//pthread_atfork( prepare, infork, infork );
sleep( 1 );
int pid = fork();
if( pid < 0 )
{
pthread_join( id, NULL );
pthread_mutex_destroy( &mutex );
return 1;
}
else if( pid == 0 )
{
printf("我是子进程,打算加锁 我的锁%p
",&mutex);
pthread_mutex_lock( &mutex );
printf("我是子进程,成功加锁
");
printf( "I can not run to here, oop...
" );
printf("我是子进程,打算解锁
");
pthread_mutex_unlock( &mutex );
printf("我是子进程,成功解锁
");
exit( 0 );
}
else
{
printf( "我是父进程,打算解锁
");
pthread_mutex_unlock( &mutex );
printf( "我是父进程,成功解锁 我的锁%p
",&mutex);
wait( NULL );
}
pthread_join( id, NULL );
pthread_mutex_destroy( &mutex );
return 0;
}
此处明明父进程已经加锁并且解锁后子进程才重新加锁,为什么会被阻塞?就是因为子进程和父进程的变量实质上是不一样的。
解决办法:
- 手动在fork前解锁mutex
pthread_mutex_unlock(&mutex);
int pid = fork();
- 使用pthread_atfork;
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击