linux进程(二)——如何创建进程?

一、如何创建进程?

linux通过fork()系统调用创建新一个进程,老进程叫父进程,复制生成的新进程叫子进程。父子关系是相对的,每一代都有一个父子关系。

fork函数定义如下:

#include <unistd.h>

pid_t fork(void);

实例1:

#include <unistd.h>  
#include <stdio.h>   

int main (void)   
{   
    pid_t fpid = -1; //fpid表示fork函数返回的值  
    printf("this is fork test.\r\n");
    fpid=fork();  
     
    if (fpid < 0){
        printf("error in fork!\r\n");  
    } else if (fpid == 0){//子进程 
    	printf("\r\n");  
        printf("fpid is %d\r\n",fpid);
        printf("child process, my PID is %d\r\n",getpid());  
        printf("child process, my PPID is %d\r\n",getppid()); 
        
    } else if (fpid > 0){//父进程  
    	printf("\r\n"); 
        printf("fpid is %d\r\n",fpid);
    	printf("parent process, my PID is %d\r\n",getpid()); 
        printf("parent process, my PPID is %d\r\n",getppid());  

    }  

	printf("hello world, pid = %d.\r\n", getpid());
    return 0;  
}  

fork的原理:当一个进程A调用fork时,系统内核创建一个新的进程B,并将A的内存映像复制到B的进程空间中,因为A和B是一样的,那么他们怎么知道自己是父进程还是子进程呢,看fork的返回值就知道,上面的实验结果也能看出:fork在子进程中返回0,在父进程中返回子进程的pid

二、父子进程对文件的操作

1.子进程继承父进程中打开的文件

父进程以O_TRUNC的方式打开文件,后续和子进程对文件进行写入

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

#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(void)
{
// 首先打开一个文件
	int fd = -1;
	pid_t pid = -1;
	
	fd = open("1.txt", O_RDWR | O_TRUNC);
	if (fd < 0)
	{
		perror("open");
		return -1;
	}
	
	// fork创建子进程
	pid = fork();
	if (pid > 0)
	{
		// 父进程中
		printf("parent.\r\n");
		write(fd, "hello", 5);
        Sleep(1);//给系统调度充足的时间
	}
	else if (pid == 0)
	{
		// 子进程
		printf("child.\r\n");
		write(fd, "world", 5);
        Sleep(1);//给系统调度充足的时间
	}
	else
	{
		perror("fork");
		exit(-1);
	}
	close(fd);
	
	return 0;
}

2、父子进程各自独立打开同一文件实现共享

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>


int main(void)
{
	// 首先打开一个文件
	int fd = -1;
	pid_t pid = -1;
	
	// fork创建子进程
	pid = fork();
	if (pid > 0)
	{
		// 父进程中
		fd = open("1.txt", O_RDWR );
		if (fd < 0)
		{
			perror("open");
			return -1;
		}
		
		printf("parent.\n");
		write(fd, "hello", 5);
		sleep(1);
	}
	else if (pid == 0)
	{
		// 子进程
		fd = open("1.txt", O_RDWR );
		if (fd < 0)
		{
			perror("open");
			return -1;
		}
		
		printf("child.\n");
		write(fd, "world", 5);
		sleep(1);
	}
	else
	{
		perror("fork");
		exit(-1);
	}
	close(fd);

	return 0;
}

结果都是world,原因如下表,父子进程文件描述符所指向的文件表是独立的。当父进程先执行的时候,写入了hello,子进程执行的时候,由于文件表独立,所以文件指针也独立,子进程是从0偏移地址写,所以会将之前写的hello覆盖掉,只剩下world。

要想实现接续写的效果,只需在open时使用O_APPEND

原因:如果用O_APPEND标志打开一个文件,则相应标志也被设置到文件表项的文件状态标志中. 每次对这种具有追加写标志的文件执行写操作时,文件表项中的当前文件偏移量首先会被设置为i节点表项中的文件长度,这就使得每次写入的数据都追加到文件的当前尾端处.

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值