求助,fork函数建立子进程后,如何让子进程和父进程共享一个变量

lin_linqq 2010-03-09 04:10:02
如程序,为什么指针相同,但是所指的值不相同?
#include <stdlib.h>
#include <unistd.h>
#include <iostream>


using namespace std;

int j = 0;

/*
*
*/
int main(int argc, char** argv) {

signal(SIGCHLD,SIG_IGN); //avoid zombie process
int *i;
i = &j;

int k=0;
pid_t pid,pid1,pid2;
cout < <"this is at beginning, pointer i is" < <i < <endl;

sleep(1);
pid = fork();
if(pid <0)
{
cout < <"create childprocess error!" < <endl;
}
else if (pid == 0)
{

cout < <"for childprocess,pointer i = " < <i < <endl;
for(k;k <10;k++)
{
(*i)++;
cout < <"for childprocess,j = " < <*i < <endl;
}


}
else if(pid > 0)
{
sleep(5);
cout < <"for fatherprocess, j = " < <*i < <endl;
cout < <"for fatherprocess, i = " < <i < <endl;

}


return (EXIT_SUCCESS);
}
输出:
this is at beginning, pointer i is0x804a0d4
for childprocess,pointer i = 0x804a0d4
for childprocess,j = 1
for childprocess,j = 2
for childprocess,j = 3
for childprocess,j = 4
for childprocess,j = 5
for childprocess,j = 6
for childprocess,j = 7
for childprocess,j = 8
for childprocess,j = 9
for childprocess,j = 10
for fatherprocess, j = 0
for fatherprocess, i = 0x804a0d4

为什么呢?i虽然被fork复制了,但是i的值一直没有改变,所以它指向的值应该是同一个值才对阿。
而无论子进程还是父进程对*i进行任何操作也应该都应该对j产生影响。

除了共享内存,还有什么办法能fork函数建立子进程后,让子进程和父进程共享一个变量j?
...全文
2048 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
guoyang1007 2010-03-10
  • 打赏
  • 举报
回复
最简单的办法,可以考虑共享文件,即在/var/建立一个文件,文件放着共享数据,使用文件锁使得进程同步
KimenWu 2010-03-10
  • 打赏
  • 举报
回复
从操作系统的角度了解,线程是也一种进程,因此,他有自己的pid
senfrans 2010-03-09
  • 打赏
  • 举报
回复
如果是进程间 就使用共享内存吧 mmap 使用相同的内存区域
线程的话就更方便 使用信号量同步即可
lin_linqq 2010-03-09
  • 打赏
  • 举报
回复
不是很明白,kill的第一个参数也可以是线程号?还是说把线程号转化成进程号?转化成进程号的线程号就能被kill接收了?
KimenWu 2010-03-09
  • 打赏
  • 举报
回复
引用 3 楼 lin_linqq 的回复:
任务颇大,用线程实现起来比较麻烦,因为进程间的通讯十分频繁,而线程间的通讯我又不太懂,就只能用进程了。
要在子进程中修改父进程的数据,需要用IPC的话,共享内存肯定是一种方法了,socket的确比较麻烦,而且在本机上有点大材小用的感觉。至于其他的IPC方法,管道,消息队列貌似都不是很适用吧。哪位还有什么建议么?

线程是可以实现变量共享的,因为所有的线程都在进程的同一地址空间。要注意的是需要做线程同步。即不能出现两个线程同时读写这个变量的情况。
lin_linqq 2010-03-09
  • 打赏
  • 举报
回复
看到资料上说用#pragma预处理命令可以放进进程共享数据,有人知道具体怎么办么?
也有人说pragma data_seg不能用于linux,等待达人给我解惑了。
brookmill 2010-03-09
  • 打赏
  • 举报
回复
引用 4 楼 lin_linqq 的回复:
另外,像大家说的那样“多进程地址空间是独立的,虽然两个指针的值相同,但他们是不同进程空间的”,谁能给解释下不同进程地址空间么?
《1》难道是说每个进程被分给一块内存?而父进程中i指的是父进程地址空间中的 0x804a0d4 ,而子进程中i指的是子进程地址空间的 0x804a0d4 ?
《2》在32位机器上,一个指针占用4个字节的大小,i应该是28位吧,不到4个字节,难道差的4位是分配给进程的地址空间么?那也太少了吧?

1. 程序里看到的指针的值,比如0x804a0d4,都是虚拟地址。每个进程都有独立的4G的虚拟地址空间,映射到不同的物理空间。比如我现在同时运行IE和QQ,他们都有可能访问各自的0x804a0d4这个虚拟地址,但是映射之后的物理内存就不会是同一个地址。
2. 把i写成0x0804a0d4就凑够32位了 :) 差的4位刚好是0
全局变量在堆上,地址比较低;如果察看一个局部变量的地址可能就会有完整的32位了。
lin_linqq 2010-03-09
  • 打赏
  • 举报
回复
另外,像大家说的那样“多进程地址空间是独立的,虽然两个指针的值相同,但他们是不同进程空间的”,谁能给解释下不同进程地址空间么?
《1》难道是说每个进程被分给一块内存?而父进程中i指的是父进程地址空间中的 0x804a0d4 ,而子进程中i指的是子进程地址空间的 0x804a0d4 ?
《2》在32位机器上,一个指针占用4个字节的大小,i应该是28位吧,不到4个字节,难道差的4位是分配给进程的地址空间么?那也太少了吧?
lin_linqq 2010-03-09
  • 打赏
  • 举报
回复
任务颇大,用线程实现起来比较麻烦,因为进程间的通讯十分频繁,而线程间的通讯我又不太懂,就只能用进程了。
要在子进程中修改父进程的数据,需要用IPC的话,共享内存肯定是一种方法了,socket的确比较麻烦,而且在本机上有点大材小用的感觉。至于其他的IPC方法,管道,消息队列貌似都不是很适用吧。哪位还有什么建议么?
KimenWu 2010-03-09
  • 打赏
  • 举报
回复
线程好像也可以互发信号。只要kill的pid是某个线程就可以了。

获取线程id的函数要封装一下:

#include <sys/syscall.h>

pid_t gettid()
{
return syscall(SYS_gettid);
}

lin_linqq 2010-03-09
  • 打赏
  • 举报
回复
引用 7 楼 lihualoveyou 的回复:
引用 3 楼 lin_linqq 的回复:任务颇大,用线程实现起来比较麻烦,因为进程间的通讯十分频繁,而线程间的通讯我又不太懂,就只能用进程了。 要在子进程中修改父进程的数据,需要用IPC的话,共享内存肯定是一种方法了,socket的确比较麻烦,而且在本机上有点大材小用的感觉。至于其他的IPC方法,管道,消息队列貌似都不是很适用吧。哪位还有什么建议么?
线程是可以实现变量共享的,因为所有的线程都在进程的同一地址空间。要注意的是需要做线程同步。即不能出现两个线程同时读写这个变量的情况。

多谢了,但是我说的进程间通讯需要收发很多信号,线程用起来稍微有些麻烦。反倒是线程同步不那么难,就是mutex就行了。不知道线程间能互发信号么?
toborac 2010-03-09
  • 打赏
  • 举报
回复
多进程地址空间是独立的 要共享数据需通过进程间通信 可参考有关书籍 比如用socket编程,共享内存等等,比较麻烦

也可考虑用多线程来解决 Linux多线程间地址空间是共享的 可参考pthread资料 产生的线程级别相同 (虽然主线程还是需要wait子线程结束) 可以直接共享变量 实际上就连打开的文件都是共享的
brookmill 2010-03-09
  • 打赏
  • 举报
回复
虽然两个指针的值相同,但他们是不同进程空间的,所以会映射到不同的物理内存。
子进程复制了父进程的数据之后,两者就完全没有关系了。
  • 打赏
  • 举报
回复
进程间通信,用共享内存吧。
mmap是一种实现方式。


systemV的shmat
http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index2.html

23,118

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧