进程操作

1、创建一个进程

#include<unistd.h>

pid_t fork(void);

返回值:
1、对于父进程,fork()函数返回新创建的子进程的ID

2、对于子进程,fork()函数返回0。由于系统0号进程是否内核进程,所以子进程的进程号不可能是0.

3、如果出错,fork()函数返回-1。

例:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(void)
{
     pid_t pid;
     pid = fork();
     if(pid<0){
           printf("fail to fork\n");
           exit(1);
     }else if (pid == 0){
	   printf("child id:%u\n",getpid());
     }else{
           printf("parent id:%u\n",pid);
     }
     return 0;
}

2、父子进程的共享资源
子进程完全复制了父进程的地址空间的内容,包括堆栈段和数据段,子进程并没有复制代码段,而是和父进程共用代码段。

例:

	

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int global;
int main(void)
{
    pid_t pid;
    int stack = 1;
    int *heap;
    heap = (int *)malloc(sizeof(int));
    *heap = 2;
    pid = fork();
    if(pid<0){
         printf("fail to fork\n");
         exit(1);
    }else if (pid == 0){
         global++;
         stack++;
	 (*help)++;
	 printf("child data:%d,stack:%d,heap:%d\n",global,stack,*heap);
    }else{
         printf("parent data:%d,stack:%d,heap:%d\n",global,stack,*heap);
    }
    return 0;
}
gcc test.c -o test
./test
child data:1,stack:2,heap:3
parent data:0,stack:1,heap:2


资源                        父子进程是否相同            备注
进程ID                      否                            父子进程是两个独立的进程,调度机会均等
实际用户ID               是
实际组ID                   是
有效用户ID               是
有效组ID                  是
附加组ID                  是
进程组ID                  是
父进程ID                  否                            父进程的进程是其他进程,而子进程的父进程是父进程
会话ID                      是
设置用户ID标志        是
设置组ID标志           是
当前工作目录           是
根目录                      是
文件权限屏蔽字       是
信号的屏蔽              是
打开文件的描述符   是
数据段                     是
代码段                     是
堆栈                         是
.bass段                    是
连接的共享存储段    是
存储映射                  是
资源限制                  是
tms_utime                否                     子进程的tms_utime被清0
tms_stime                否                     子进程的tms_stime被清0
tms_cutime              否                     子进程的tms_cutime被清0
tms_ustime              否                     子进程的tms_ustime被清0
fork函数的返回值    否                      父进程返回子进程的进程ID,而子进程返回0
设置的文件锁          否                      文件锁不会被继承
未处理的闹钟信号   否                      子进程清除未处理的闹钟信号
未决信号集              否                     子进程清除未处理的未决信号

2、创建一个共享空间的子进程

创建一个共用父进程地址空间的子进程

#include<unistd.h>

pid_t vfork();

vfork()函数和fork()函数的区别有以下两点

1、vfork()函数产生的子进程和父进程完全共享地址空间,包括代码段、数据段和堆栈段,子进程对这些共享资源所做的修改可以影响进程。由此可知,vfork()函数与其他说是产生了一个进程,不如说是产生了一个线程。
2、vfork()函数产生的子进程一定比父进程先运行,也就是说父进程调用了vfork()函数后,会等待子进程运行后再运行。

例:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int global;
int main(void)
{
	pid_t pid;
	int stack = i;
	int *heap;
	heap = (int *)malloc(sizeof(int));
	*heap = 2;
	pid = vfork();
	if(pid<0){
		printf("fail to fork\n");
		exit(1);
	}else if (pid == 0) {
		global++;
		stack++;
		(*help)++;
		printf("child data:%d,stack:%d,heap:%d\n",global,stack,*heap);
		printf("child terminates\n");
		exit(0);
	}else {
	        //sleep(2);
		printf("parent data:%d,stack:%d,heap:%d\n",global,stack,*heap);
		printf("parent terminates\n");
		return 0;
       }
}
gcc test.c -o test
./test
child data:1,stack:2,heap:3
child terminates
parent data:1,stack:2,heap:3
parent terminates

3、退出进程
#include<stdlib.h>

void exit(int status);

这个退出函数会深入内核注销掉的内核数据结构,并且释放进程的资源。

例:

#include<stdlib.h>
int main(void)
{
       exit(4);
}
gcc -exit.c -o exit
$./exit
$echo $?
4

c程序中的return 语句会被编译器翻译为调用exit()函数
return 1  会被编译器翻译为调用exit(1)函数
4、设置进程所有者

a、改变一个进程的实际用户ID和有效用户ID

      #include<unistd.h>

      int setuid(uid_t uid);

      参数:改变后的新用户ID

      返回:成功返回0,失败返回-1

      只有两种用户可以修改进程的实际用户ID和有效用户ID
      1、根用户,根用户可以将进程的实际用户ID 和有效用户ID更改。

      2、其他用户,且该用户的用户ID等于进程和实际用户ID或者保存的用户ID

b、只修改有效用户ID函数

      #include<unistd.h>

      int seteuid(uid_t uid);

      参数:修改ID

      返回:成功返回0,失败返回-1.

c、修改实际组ID和有效组ID的函数

      #include<unistd.h>
      int setgid(gid_t gid)
     int setegid(gid_t gid)




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值