UNIX环境编程(c语言)--多进程(一)--基础知识

基础知识

main函数

c程序总是在main函数开始执行的,main的原型为

int main(int argc, char **argv)

其中 argc 是命令行参数的个数,argv是各参数按序组成的指针数字
argv[0] 通常是程序名,argv[1]是第一个参数,argv[argc -1]最后一个参数
argv[ argc] 将是一个空指针

进程的终止

进程的终止有八种方式
正常的终止有:main返回、调用exit、调用_exit ( _Exit )、最后一个线程返回、最后一个线程调用pthread_exit
异常终止有:调用abort、接到一个信号、最后一个进程对取消请求做出响应

以上还有一些目前尚未涉及到的,以后更新再说。
其中exit函数,会清理关闭标志io库对所有打开流调用fclose,输出缓冲所有的数据都被冲洗(就是被写到文件上)

在main中调用return时,return会去调用exit,但是在其他函数内的return不会去调用exit,就是说其他函数内的return不会导致进程退出

如果main定义时,不声明为返回值int,进程终止状态可能会是随机值

终止处理程序 和 atexit函数

在我们调用exit去终止一个进程时,exit会先调用登记好的终止处理程序,最后通过fclose关闭所有打开流

我们可以使用函数atexit来登记终止处理函数,一个进程最多登记32个函数
原型

int atexit(void (*func)(void));
/* 成功返回0,失败返回 非0 */

atexit的参数是一个函数指针,该函数是一个没有参数也没有返回值的函数
exit调用这些函数的顺序和登记的顺序相反,一个函数登记多次,也会被调用多次

使用实例

void aaa(void)
{
    .....;
}

atexit(aaa);

程序的终止过程:
程序的终止

环境表

每个程序都会接收一个环境表,和命令行参数表一样,也是字符指针数组
其中每个指针指向一个以 ‘\0’ 结束的字符串,且最后一个指针值是NULL
全局变量environ包含了这个指针数组的首地址

每个字符串都是 name=value 的形式

我们来写一个程序,打印一下命令行参数列表和环境表

  1 #include <stdio.h>
  2
  3 extern char **environ;
  4
  5 int main(int argc , char **argv)
  6 {
  7     int         i = -1;
  8     for(i = 0; i < argc; i++)
  9     {
 10         printf(" argv[%d] %s \n", i, argv[i]);
 11     }
 12
 13     for(i = 0; environ[i] != NULL ; i++)
 14     {
 15         printf("environ %d : %s \n",i, environ[i]);
 16     }
 17
 18     return 0;
 19 }
 20
 21

运行结果为
在这里插入图片描述
在这里插入图片描述

环境变量函数 getenv putenv setenv等

如上,我们查看到的环境表的每一项都是 name=value的形式
实际上我们不必直接访问enveron,可以通过一些函数来取得所需环境变量的值

注意: 我们只能修改当前进程和子进程的环境,而不能改变父进程的环境

char *getenv(const char *name);
/*  返回name对应的 value的指针,未找到则返回NULL */

int putenv(char *str);
/*  成功返回0,失败返回非0 */

int setenv(const char *name, const char *value, int rewite);
/*  成功返回0,失败返回-1 */

int unsetenv(const char *name);
/*  成功返回0,失败返回-1 */

putenv :
参数str 是 name=value形式的字符串,该函数将其加入环境表中,如果name已经存在先删除原来的定义,再添加

setenv:
将name的值设置为value,如果环境中已经存在name,rewite为0时则不删除原定义、不设置新值、也不出错,rewite为非0时,先删除原定义再添加

unsetenv:
删除name的定义,不存在也不报错

进程标识

进程ID:
每个进程都有一个非负整数表示的进程ID,且这个ID是唯一的,但是也可被复用

进程ID 0 :
0号ID是调度进程,也叫交换进程,是内核的一部分,是系统进程

进程ID 1 :
1号ID是init进程,在自检完成后由内核调用,是一个有超级用户权限的用户进程,在系统运行过程中init进程永远不会退出。当其他进程的父进程死了后,会被init进程 ‘领养’。

查看进程ID

//返回调用进程的进程ID
pid_t getpid(void);

// 返回调用进程的父进程ID
pid_t getppid(void);

// 返回调用进程的实际用户id
uid_t getuid(void);

// 返回调用进程的有效用户ID 
uid_t geteuid(void);

// 返回调用进程的实际组id
gid_t getgid(void);

// 返回调用进程的有效组id
gid_t getegid(void);

有效用户和实际用户

有效用户ID和有效用户组ID:
进程用来决定我们对资源的访问权限。一般情况下,有效用户ID等于实际用户ID,有效用户组ID等于实际用户组ID。当设置-用户-ID(SUID)位设置,则有效用户ID等于文件的所有者的uid,而不是实际用户ID;同样,如果设置了设置-用户组-ID(SGID)位,则有效用户组ID等于文件所有者的gid,而不是实际用户组ID。

实际用户:表示一开始执行程序的用户,比如用账号iceup登录shell,然后执行程序ls,那么实际用户就是iceup。
有效用户:有效用户是指在程序运行时,计算权限的用户

关于SUID和SGID 请点击查看文章:Linux系统学习—用户管理及权限管理(三)

进程资源限制的查询和修改 getrlimit setrlimit

每个进程都有一组资源限制,我们可以使用getrlimit setrlimit 进行查询和修改

原型

struct rilimit{
	rlim_t rlim_cur;  //  软件限制
	rlim_t rlim_max;  //  硬件限制
};

int getrlimit(int resource,  struct rilimit *rlptr);
int setrlimit(int resource,  const struct rilimit *rlptr);
/* 成功返回0,失败返回非0*/

在修改资源限制时,应当遵守下列规则

  1. 软件限制必须小于或对应硬件限制

  2. 普通进程只能降低硬件限制,但是硬件限制要保持大于等于软件限制,对于普通用户来说,这种减低是不可逆的

  3. 超级用户程序可以提高硬件限制

    常量RLIM_INFINITY 代表无限量
    

参数resource是对应的资源,下面将列出

  • RLIMIT_AS:进程可用存储区的最大总长度(字节),这会影响sbrk函数和mmap函数
  • RLIMIT_CORE:core文件的最大字节数,若其值为0则阻止创建core文件
  • RLIMIT_CPU:CPU时间的最大量值数(秒),当超过此软限制,向该进程发送SIGXCPU信号
  • RLIMIT_DATA:数据段的最大字节长度,就是初始化数据、非初始以及堆的总和
  • RLIMIT_FSIZE:可以创建的文件的最大字节长度。当超过此软限制,则向该进程发送SIGXFSZ信号
  • RLIMIT_LOCKS:一个进程可持有的文件锁的最大数
  • RLIMIT_MEMLOCK:一个进程使用mlock能够锁定在存储器中的最大字节数
  • RLIMIT_NOFILE:每个进程能打开的最大文件数。更改此限制将影响到sysconf函数在参数_SC_OPEN_MAX返回的值
  • RLIMIT_NPROC:每个实际用户ID可拥有的最大子进程数。更改此限制将影响到sysconf函数在参数_SC_CHILD_MAX返回的值
  • RLIMIT_RSS:最大驻内存集的字节长度。如果物理存储器供不应求,则内核将从进程处取回超过RSS的部分
  • RLIMIT_SBSIZE:用户在任一给定时刻可以占用的套接字缓冲区的最大长度
  • RLIMIT_STACK:栈的最大字节长度
  • RLIMIT_VMEM:这个是RLIMIT_AS的同义词
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GuanFuXinCSDN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值