接上一篇: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.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;
}
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;
}
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上发布的文章类型导读】