linux下fork的使用

系统调用Fork

需要包含头文件

#include <sys/types.h> 
#include <unistd.h> 

函数声明

pid_t fork(void);   

其中pid_t在sys/types.h中定义:

typedef __pid_t pid_t;

可以看到只是一个int.

fork()通过复制调用过程来创建一个新过程。 新进程称为子进程,与调用进程(称为父进程)完全相同,但以下几点除外:

  • 子进程具有其自己的唯一进程ID,并且此PID与任何现有进程组的ID(setpgid(2))不匹配。
  • 子级的父进程ID与父级的进程ID相同。
  • 子级不会继承其父级的内存锁(mlock(2),mlockall(2))。
  • 子进程中的进程资源利用率(getrusage(2))和CPU时间计数器(times(2))被重置为零。
  • 孩子的未决信号集最初是空的(sigpending(2))。
  • 子级不会从其父级继承信号量调整(semop(2))。
  • 子级不会从其父级(fcntl(2))继承记录锁。
  • 父级不会从其父级继承计时器(setitimer(2)警报(2),timer_create(3))。
  • 子级不会从其父级(aio_read(3),aio_write(3))继承未完成的异步I / O操作。
  • 子级不会从其父级继承目录更改通知(通知)(请参阅fcntl(2)中对F_NOTIFY的描述)。
  • 重置prctl(2)PR_SET_PDEATHSIG设置,以使子级在其父级终止时不接收信号。
  • 带有madvise(2)MADV_DONTFORK标志标记的内存映射不会在fork(2)上继承。
  • 子项的终止信号始终为SIGCHLD(请参见clone(2))。
  • 子进程是通过一个线程创建的,该线程称为fork(2)。父级的整个虚拟地址空间都在子级中复制,包括互斥体的状态,条件变量和其他pthreads对象;使用pthread_atfork(3)可能有助于解决可能导致的问题。
  • 子级继承父级打开文件描述符集的副本。子级中的每个文件描述符都引用与父级中相应的文件描述符相同的打开文件描述(请参阅open(2))。这意味着这两个描述符共享打开文件状态标志,当前文件偏移和信号驱动的I
    / O属性(请参阅fcntl(2)中对F_SETOWN和F_SETSIG的描述)。 *
    子级继承父级的开放消息队列描述符集的副本(请参阅mq_overview(7))。子级中的每个描述符与父级中的相应描述符引用相同的打开消息队列描述。这意味着两个描述符共享相同的标志(mq_flags)。

测试代码

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main(int argv,char *argc[])
{
	printf("before fork:%d",getpid());
	int pid=fork();
	printf("hello world:%d",getpid());
	if(pid>0)
	{
		while(1)
		{
			sleep(1);
		}
	}
	else if(0 == pid)
	{
		//子进程
		while(1)
		{
			printf("child process:%d\n",getpid());
			printf("my father's process:%d\n",getppid());
			sleep(1);
		}
		
	}
	else if(-1 == pid)
	{
		//fork错误
		printf("fork error\n");
	}
}

运行结果:
在在fork之前,父进程打印一次hello world,随即子进程也打印出hello world.
注意打印信息和fork的位置。

发布了12 篇原创文章 · 获赞 0 · 访问量 297

猜你喜欢

转载自blog.csdn.net/ASCE_S/article/details/103749597