Linu学习总结(三)

Linu学习总结(三)

文件时间属性修改与时间处理

如果要修改某特定文件的访问时间和修改内容时间,可以调用utime()函数

int utime(_const char *_file, _const struct utimbuf *_file_times)
struct utimbuf
{
    _time_t actime;//访问时间
    _tiem_t modtime;//修改内容时间
}

进程管理与程序开发

内核空间进程资源即PCB相关的信息。包含进程控制块本身、打开的文件表项、当前目录、当前终端信息、线程基本信息、可访问内存地址空间、PID、PPID、UID、EUID等。也就是说,内核通过PCB可以访问该进程所有的资源。这些资源只能通过系统调用才能访问。这一资源在当前进程退出,只能由另一进程来回收。

进程状态

用户级进程拥有以下几种状态:就绪/运行状态、等待状态(可以被中断打断)、等待状态(不可被中断打断)、停止状态和僵尸状态。

TASK_RUNNING:正在运行或处于就绪状态。就绪状态就是指进程申请到了除CPU外其他的所有需要的资源
TASK_INTERRUPTIBLE:处于等待队伍中,等待资源有效时唤醒,但可以被中断唤醒
TASK_UNINTERRUPTIBLE:处于等待队伍中,等待资源有效时唤醒,但不可以被中断唤醒。
TASK_ZOMBIE:进程资源用户空间被释放,但内核中的进程PCB并没有释放,等待父进程回收
TASK_STOPPED:进程被外部程序暂停(如收到SIGSTOP信号),当再次允许时继续执行(如收到SIGCONT信号),因此处于这一状态可以被唤醒。

进程基本属性

与进程本身相关的属性包括进程号(PID)、父进程号(PPID)、进程组号(PGID)。
进程号:是系统维护的唯一标识一个进程的正整数,进程号是无法在用户级层面修改的。在linux操作系统中,系统的第一个用户进程为init进程,他的PID为1,其他的进程PID依次增加。用户可以通过ps aux命令查看当前系统所有进程的基本属性
在应用编程中,调用getpid()函数可以获得当前进程的PID

_pid_t getpid(void);

如果执行成功将返回当前进程的PID,类型为pid_t;如果执行失败则返回-1
父进程号:任何进程(除init进程)都是有另一个进程创建,该进程称为创建进程的父进程,被创建的进程称为子进程。父进程的进程号(PID)即为子进程的父进程号

_pid_t getppid(void);

此函数如果执行成功将返回当前进程的父进程PID,类型为pid_t;如果执行失败则返回-1
进程组号:进程组是一个或多个进程的集合。他们与同一作业相关联,可以接受来自同一终端的各种信号,每一个进程组都有唯一的进程组号,进程组号可以在用户层修改
用户可以通过调用getpgid()函数来获得进程的进程组号

_pid_t getpgid(_pid_t _pid);

参数为要获得进程组号的进程号,如果为0表示获取当前进程组号,否则为指定进程的PGID。如果执行成功则返回进程的进程组号,否则返回-1.
函数pid_t getpgrp(void);也可以用来获取当前进程的进程组号
每一个进程组都可以有一个组长进程,组长进程的进程组号等于其进程号,但是进程可以先退出,只要在进程组中有一个进程存在,则该进程组就存在,与其组长进程是否终止无关。进程的最后一个进程可以终止,或者转移到另一个进程组
将摸个进程加到某个进程组的系统调用函数setpgid(),

int setpgid(pid_t pid, pid_t pgid);

其第一个参数为要修改进程PGID的进程PID,第二个参数为新的进程组号,如果两个参数相等,则有pid制定的进程变成进程组组长,如果pid为0,则修改当前进程的PGID,如果pgid是0,则由pid制定的进程的PID将用于进程组号的PGID
会话:(session)是一个或多个进程组的集合。系统调用的getsid()用来获取某个进程的会话SID

_pid_t getsid(_pid_t _pid);

如果pid是0,返回调用进程的会话号SID,一般来说,该值等于进程组号,如果pid并不属于调用者所在的会话,则调用者就不能获得SID
,某进程的会话SID是可以修改的,函数setsid()用来创建新会话

_pid_t setsid(void);

如果调用进程已经是一个进程组的组长,则此函数返回错误。
进程用户属性:linux是权限有严格控制的操作系统,某个进程拥有真实的用户号(RUID)、真实用户组号(RGID)、有效用户号(EUID)、有效用户组号(EGID)信息。
进程真实用户号(RUID):创建该进程的用户的UID为此进程的真实用户号。可以调用getuid()函数来获得当前的真实用户号

_uid_t getuid(void);

如果执行成功将返回当前进程的UID,如果执行失败,则返回-1

进程有效用户号(EUID):主要用于权限检查。多数情况下,EUID和UID相同。如果可执行文件的setuid位有效,则该文件的拥有者之外的用户运行该程序时,EUID和UID不相同,当设置了setgid位后,任何用户运行该程序时,其有效用户组EUID为该文件的拥有者 。

进程用户组号(GID):创建进程的用户所在的组号为该进程的进程用户组号,可以通过调用getgid()函数来获得当前进程的真实用户组号

_uid_t getgid(void);

执行成功将返回当前进程的GID;如果执行失败则返回-1
有效进程用户组好(EGID):一个情况下,EGID和GID相同,但是,当某可执行文件设置了setgid位,那么任何用户运行此程序时,其有效用户组号为该文件的拥有者所在的组

_uid_t getegid(void);

如果执行成功将返回当前进程的EGID;如果执行失败则返回-1

进程管理及控制

创建进程:在linux环境下,创建进程的主要方法是fork()函数

_pid_t fork(void);

如果执行成功,在父进程中奖返回子进程的PID,子进程将会返回0,以区别父子进程
如果执行失败,则在父进程中将返回-1
fork函数调用成功后,将为子进程申请PCB和用户空间。子进程会复制父进程几乎所以的信息,在用户空间将复制父亲用户空间所有的数据(代码段、数据段、BSS、堆、栈),子进程将会从父进程继承下列属性:有效用户/组号、进程组号、环境变量、对文件的执行的关闭标志、信号处理方式设置、信号屏蔽集合、当前工作目录、跟目录、文件模式掩码、文件大小限制,打开文件的描述符。

vfork()函数创建新进程时并不复制父进程的地址空间,而是在必要的时候才申请新的存储空间,vfork()比fork()可以很大程度上提高性能,vfork()只在需要的时候复制,而一般采用与父进程共享所有的资源的方式处理

_pid_t vfork(void);

vfork()在子进程环境中返回0,在父进程中返回子进程的进程号

在进程中运行新代码

用fork()函数创建子进程后,如果希望在当前进程中运行新的程序,则可以调用execX系列函数
execl()函数声明:

int execl(_const char *_path, _const char *_arg,...);

参数path字符串所指向的程序,第二个及以后的参数代表执行文件时传递的参数列表,最后一个参数必须是空指针以参数列表为空,如果执行成功,不返回,否则返回-1

execle()函数

int execle(_const char *_path, _const char *_arg,...)

execle()用来执行参数path字符串所指向的程序,第二个及以后参数代表执行文件时传递的参数列表,最后一个参数必须指向一个新的环境变量数组
execlp()函数

int execlp(_const char *_file, _cosnt char *_arg,...);

execlp()会从环境变量所指的目录中查找文件名为第一个参数指示的字符串,找到后执行该文件,第二个及以后的参数代表执行文件时传递的参数列表,最后一个参数必须用到空指针NULL
execv()函数

int execv (_const char *_path, char *_const _argv[]);

execv()用来执行参数path字符串所指向的程序,第二个参数为数组指针维护的程序参数列表。该数组的最后一个成员必须为NULL
execvp()函数

int execvp(_const char *_file, char *_const _argv[])

execvp()会从环境变量所知的目录中查找文件名为第一个参数所示的字符串,找到后执行该文件,第二个及以后的参数代表执行时传递的参数列表,最后一个成员必须为NULL
system()以新进程方式运行一个程序,然后结束。system()函数用来创建新进程,并在此进程中运行新进程,直到新进程结束后,才继续运行父进程。子进程结束后,会返回退出状态

int system(_cosnt char *_command)

回收进程用户空间资源

在linux系统下,可以通过以下方式结束进程
显示调用exit或_exit系统调用
在main函数中执行return语句
隐含的离开main函数,例如遇到main函数的“”}
函数exit()用于退出进程

void exit(int _status)

exit()与return的区别
return退出当前函数,exit()函数退出当前进程
return仅从子函数中返回,并不退出进程,调用exit()时要调用一段终止处理程序,然后关闭所有的I/O流。
_exit函数不调用任何注册函数而直接退出进程

void _exit(int _status);

_exit()仅把参数status返回给父进程而直接退出。此函数调用后不会返回,而是传递SIGCHLD信号给父进程,父进程可以通过
wait()函数获得子进程的结束状态,_exit()不会处理标准I/O缓冲区,如果要更新需要调用exit()
注册退出处理函数
函数atexit()和on_exit()用来注册在执行exit()函数前执行注册的操作函数

int atexit(void(*_func) (void));
int on_exit(void(*_func)(int_status, void *_arg),void *_arg);

两个函数的功能都是告诉进程,在正常退出时执行注册的func函数。两者的差异仅仅是atexit注册的函数没有参数。而on_exit注册的函数带参数,类型为void(*_func)(int _status, void *_arg)
第一个参数为退出的状态,在执行exit()函数时此参数值为exit()函数的参数
第二个参数为用户输入的信息,一个无类型的指针,用户可以指定一段代码位置或输出信息

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值