当前位置:   article > 正文

linux_进程类相关学习-fork函数-getpid函数-getppid函数-getuid函数-geteuid函数-getgid函数-getegid函数-进程之间共享数据-进程gdb调试

getppid

接上一篇:linux_环境变量-C语言代码打印环境变量-getenv函数-setenv函数-unsetenv函数

本次来分享进程类相关的学习,主要就是分享一些函数的使用,来,开始上菜:

1.fork函数

函数作用:
  创建一个子进程。
头文件:
  #include <unistd.h>
函数原型:
  pid_t fork(void);
函数参数:
  无
返回值:
  失败返回-1;
  成功返回:
    ①父进程返回子进程的ID(非负)
    ②子进程返回 0
    即返回值>0为父进程,为0表示子进程

pid_t类型表示进程ID,但为了表示-1,它是有符号整型。(0不是有效进程ID,init最小,为1)

注意:子进程之间不能通过全局变量进行通信。

例子:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int var = 34;
int main(void)
{
    pid_t pid;
    pid = fork();//创建子进程
    if (pid == -1 ) 
    {
    	//-1表示失败
        perror("fork error: ");
        exit(1);
    }
    else if (pid > 0)
    {
        sleep(2);//暂停2s
        printf("var = %d\n", var);
    }
    else if (pid == 0) 
    {
        var = 100;//测试进程与进程之间能否用全局变量通信
        printf("var = %d\n", var);
    }
    printf("var = %d\n", var);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

1.1.循环创建n个子进程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//循环创建5个子进程
int main(void)
{
    int i;
    pid_t pid;
    printf("qqqqqqqqqqqqqqqqq\n");
	for (i = 0; i < 5; i++)
	{
        pid = fork();//创建子进程
        if (pid == 0) 
		{
            break;
        }
    }
	if (i < 5) 
	{
        sleep(i);//暂停is
        printf("I'am %d child\n", i+1);
	} 
	else  
	{
        sleep(i);
        printf("I'm parent\n");
    }
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

2.getpid函数

函数作用:
  获取当前进程ID
头文件:
  #include <sys/types.h>
  #include <unistd.h>
函数原型:
  pid_t getpid(void);
函数参数:
  无
返回值:
  返回当前进程ID

3.getppid函数

函数作用:
  获取当前进程的父进程ID
头文件:
  #include <unistd.h>
  #include <sys/types.h>
函数原型:
  pid_t getppid(void);
函数参数:
  无
返回值:
  返回当前进程的父进程ID
注意,区分一个函数是“系统函数”还是“库函数”依据:
  ①是否访问内核数据结构
  ② 是否访问外部硬件资源 二者有任一 → 系统函数;二者均无 → 库函数

4.例子:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int var = 68;
int main(void)
{
    pid_t pid;//进程号
    pid = fork();//创建一个子进程
    if (pid == -1 ) 
    {
        perror("fork");
        exit(1);
	} 
	else if (pid > 0) 
    {
		//父进程
        sleep(2);
		//getpid获取当前进程的ID
		//getppid获取父进程的ID
        printf("I'm parent pid = %d, parentID = %d, var = %d\n", getpid(), getppid(), var);
    } 
    else if (pid == 0) 
    {
		//子进程
        var = 100;
        printf("I'm child  pid = %d, parentID=%d, var = %d\n", getpid(), getppid(), var);
    }
    printf("var = %d\n", var);
    return 0; 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

5.getuid函数-geteuid函数

头文件:
  #include <unistd.h>
  #include <sys/types.h>
函数原型:
  uid_t getuid(void); //函数作用:获取当前进程实际用户ID
  uid_t geteuid(void);//函数作用:获取当前进程有效用户ID
函数参数:
  无
返回值;
  返回对应的ID

6.getgid函数-getegid函数

头文件:
  #include <unistd.h>
  #include <sys/types.h>
函数原型:
   gid_t getgid(void);//函数作用:获取当前进程使用用户组ID
   gid_t getegid(void);//函数作用:获取当前进程有效用户组ID
函数参数:
  无
返回值:
  返回对应的ID

7.进程共享

fork之后:
  父子相同处: 1.全局变量 2. .data 3. .text 4.栈 5.堆 6.环境变量 7.用户ID 8.宿主目录 9.进程工作目录 10.信号处理方式…
  父子不同处: 1.进程ID 2.fork返回值 3.父进程ID 4.进程运行时间 5.闹钟(定时器) 6.未决信号集
父子进程间遵循读时共享写时复制的原则。
父子进程不能共享全局变量。

重点:
父子进程共享:
  1. 文件描述符(打开文件的结构体)
  2. mmap建立的映射区 (后续在分享)

注意:fork之后父进程先执行还是子进程先执行不确定。取决于内核所使用的调度算法。

本章会在后续再次分享,请各位网友耐心等待。

8.gdb调试

  使用gdb调试的时候,gdb只能跟踪一个进程。可以在fork函数调用之前,通过指令设置gdb调试工具跟踪父进程或者是跟踪子进程。
  默认跟踪父进程:
    set follow-fork-mode child 命令设置gdb在fork之后跟踪子进程。
    set follow-fork-mode parent 设置跟踪父进程。
注意,一定要在fork函数调用之前设置才有效。

以上就是本次分享了,希望能对广大网友有所帮助!

此博主在CSDN发布的文章目录:【我的CSDN目录,作为博主在CSDN上发布的文章类型导读

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/210200
推荐阅读
相关标签
  

闽ICP备14008679号