注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

多多的爹

 
 
 

日志

 
 

读程序,学习Linux编程(十八)  

2010-08-22 00:07:22|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

3.11. fork

接下来进入makedaemon,在了解如何将进程变成精灵进程前,先了解里面的几个函数。第一个是fork。

fork是Linux中一个比较神奇的函数。他将本身这个进程copy了一份,新出来儿子进程跟父进程几乎是相同的,并且也同样从fork调用后继续执行。调用fork后,父进程的fork会返回子进程的进程id。而子进程的fork只会返回0。因此,通过fork的返回值,你可以判断自己是父进程还是子进程。如果返回-1,表示fork失败,我还真没遇到过。

#include

int fork( void );

前面说了,fork做的是copy,不是share,所以虽然子进程拥有和父进程同样的数据,代码,堆,栈等,但这些数据是独立的,子进程的修改不会影响父进程,父进程对数据的修改也不会影响子进程。(后面会提到,其实刚刚fork出来后,数据还只是一份的,只是子进程为它增加了一个引用,只有当修改数据时,才会将数据拷贝一份出来再写。Windows里也有这类机制,好像是叫Copy-On-Write,不过这类的知识,我觉得只能拿来跟人炫耀,一点用没有)

根据我的个人体会,fork有两个用处。

第一是替代了线程的功能。貌似玩Linux的对线程一大堆的牢骚,凡是Linux下介绍线程的文章,都先提出一大套理由批判这个东西。他们更愿意用fork来担当线程的作用。如果后面有讲线程的章节再提。

第二就是为了启动另外一个进程。这个在后面的exec中会提到。这也是让人奇怪的东西。反正搞Linux的人思维总让人不明白。

fork有个让我觉得有个很恶心的地方。用gdb调试进程,进程fork后,剩下的工作交给子进程,自己sleep了,你只能干瞪眼。

结合上一节的内容,参考下面这个例子:

main()

{

char tmp_name[] = "test_temp_XXXXXX";

int fd = mkstemp(tmp_name);

void* p = mmap(0, 64, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

unlink(tmp_name);

if (p == MAP_FAILED)

{

perror("failed to create shared memory");

exit(1);

}

ftruncate(fd, 64);

memset(p, 64, 0);

char* p2 = (char*)p;

if (fork() == 0)

{

printf("{%d}I am son\n", getpid());

sleep(1);

sprintf(p2, "A message from %d\n", getpid());

printf("{%d}%s", getpid(), p2);

}

else

{

printf("{%d}I am father\n", getpid());

sleep(2);

printf("{%d}%s", getpid(), p2);

}

}

  评论这张
 
阅读(1)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017