`

用户标识和进程调度

阅读更多
    任一进程都可以得到其实际用户 ID 和有效 ID 及组 ID。但有时希望找到运行该程序用户的的登录名。通常情况下可以调用 getpwuid(getuid()) 来得到,但如果一个用户有多个登录名,这些登录名又对应着同一个用户 ID(但登录 shell 不同)时,就可以考虑使用 getlogin 函数来获取此登录名。
#include <unistd.h>
char *getlogin(void);
                 /* 返回值:若成功,返回指向登录名字符串的指针;否则,返回 NULL */

    如果调用此函数的进程没有连接到用户登录时所用的终端,则函数会失败。通常称这些进程为守护进程(daemon)。
    给出了登录名,就可用 getpwnam 在口令文件中查找用户的相应记录,从而确定其登录 shell 等。

    UNIX 系统历史上对进程提供的只是基于调度优先级的粗粒度的控制。进程可以通过增大 nice 值选择以更低优先级运行,而只有特权进程允许提高调度权限。Single UNIX Specification 中 nice 值的范围在 0~2*NZERO-1 之间,有些实现支持 0~2*NZERO(注意:定义 NZERO 的头文件因系统而异。Linux 3.2.0 还可以通过非标准的 sysconf 参数 _SC_NZERO 来访问 NZERO 值)。
    进程可以通过 nice 函数获取或更改它的 nice 值,但无法影响任何其他进程的 nice 值。
#include <unistd.h>
int nice(int incr);
                   /* 返回值:若成功,返回新的 nice 值或 NZERO;否则,返回 -1 */

    incr 参数被增加到调用进程的 nice 值上。如果它过大或过小,系统都会无声无息地把它降到最大合法值或提高到最小合法值。由于 -1 是合法的成功返回值,所以在调用 nice 函数之前需要清除 errno,在 nice 返回 -1 时需要检查它的值,以便确认是否是调用失败。
    getpriority 函数也可以获取进程的 nice 值,还可以获取一组相关进程的 nice 值;setpriority 函数则可以为进程、进程组和属于特定用户 ID 的所有进程设置优先级。
#include <sys/resource.h>
int getpriority(int which, id_t who);
          /* 返回值:若成功,返回 -NZERO~NZERO-1 之间的 nice 值;否则,返回 -1 */
int setpriority(int which, id_t who, int value);
         /* 返回值:若成功,返回 0;否则,返回 -1 */

    其中,which 参数可以取以下 3 个值之一:PRIO_PROCESS 表示进程,PRIO_PGRP 表示进程组,PRIO_USER 表示用户 ID。如果 which 作用于多个进程,则返回其中优先级最高的(最小的 nice 值)。who 参数选择感兴趣的一个或多个进程。如果 who 为 0,表示调用进程、进程组或者用户(取决于 which 参数的值)。value 参数会增加到 NZERO 上,然后变为新的 nice 值。
    下面这个程序度量了调度进程 nice 值的效果:两个进程并行运行,各自增加自己的计数器。父进程使用了默认的 nice 值,子进程以调整后的 nice 值运行 10s 后,两个进程都打印各自的计数器并终止。通过比较不同 nice 值的进程的计数值的差异就可以了解 nice 值是如何影响进程调度的。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>

unsigned long long count;
struct timeval end;

void checktime(char *str){
	struct timeval	tv;
	gettimeofday(&tv, NULL);
	if(tv.tv_sec>=end.tv_sec && tv.tv_usec>=end.tv_usec){
		printf("%s count = %lld\n", str, count);
		exit(0);
	}
}

int main(int argc, char *argv[]){
	pid_t	pid;
	char	*s;
	int		nzero, ret;
	int		adj = 0;

	setbuf(stdout, NULL);	// disabled the buffer on stdout
#if defined(NZERO)
	nzero = NZERO;
#elif defined(_SC_NZERO)
	nzero = sysconf(_SC_NZERO);
#else
	#error NZERO undefined
#endif
	printf("NZERO = %d\n", nzero);
	if(argc == 2)
		adj = strtol(argv[1], NULL, 10);
	gettimeofday(&end, NULL);
	end.tv_sec += 10;		// run for 10 seconds

	if((pid=fork()) < 0){
		printf("fork failed\n");
	}else if(pid == 0){
		s = "child";
		printf("current nice value in child is %d, adjusting by %d\n", nice(0)+nzero, adj);
		errno = 0;
		if((ret=nice(adj)) == -1 && errno != 0)
			printf("child set scheduling priority error\n");
		printf("now child nice value is %d\n", ret+nzero);
	}else{
		s = "parent";
		printf("current nice value in parent is %d\n", nice(0)+nzero);
	}
	for(;;){
		if(++count == 0){
			printf("%s counter wrap quit\n", s);
			exit(2);
		}
		checktime(s);
	}
}

    执行程序两次:一次用默认的 nice 值,另一次用最高有效 nice 值(最低调度优先级)。程序运行在单处理器 Linux 系统上,以显示调度程序如何在不同 nice 值的进程间进行 CPU 的共享。否则,对于有空闲资源的系统(如多处理器系统或多核 CPU),两个进程可能无需共享 CPU(运行在不同的处理器上),就无法看出具有不同 nice 值的两个进程的差异。
$ ./niceDemo.out                  # 默认 nice 值
NZERO = 20
current nice value in parent is 20
current nice value in child is 20, adjusting by 0
now child nice value is 20
parent count = 125786180
child count = 125607852           # 可见同父进程平等调度

$ ./niceDemo.out 20               # 最高 nice 值
NZERO = 20
current nice value in parent is 20
current nice value in child is 20, adjusting by 20
now child nice value is 39
parent count = 229924425
child count = 3317494              # 可见 CPU 占比远低于父进程

分享到:
评论

相关推荐

    单处理器系统的进程调度

    然后完成进程创建原语和进程调度原语;最后编写主函数对所作工作进程测试。 4.提示与讲解 这个实验主要要考虑三个问题:如何组织进程、如何创建进程和如何实现处理器调度。 考虑如何组织进程,首先就要设定进程...

    基于优先级的进程调度实验

    本实验的主要目的在于通过模拟优先级调度算法,深入了解进程概念和进程调度过程。实验中,我们使用了C语言在Linux操作系统下编写程序,模拟了优先级程调度算法。程序中,每个进程用一个进程控制块(PCB)来表示,PCB...

    操作系统实验一: 进程调度

    通过实验加强对进程调度算法的理解和掌握。 二、实验内容 编写程序实现基于优先级的时间片轮转调度算法。 三、实验要求 1、假定系统有5个进程,每个进程用一个进程控制块PCB来代表, 其中: 进程名:作为进程...

    进程调度算法模拟程序设计

    进程调度算法模拟程序设计,利用优先级进行调度, (1)用C语言(或其它语言,如Java)实现对N个进程采用某种进程调度算法(如动态优先权调度)的调度。 (2)每个用来标识进程的进程控制块PCB可用结构来描述,包括...

    《操作系统》进程调度算法模拟

    通过对《操作系统》进程调度算法模拟的实验,我们可以更好地理解进程的基本概念和进程调度算法的工作原理。动态优先权调度算法是操作系统中的一种常用算法,它可以根据进程的优先权来确定其执行顺序。

    进程调度算法 操作系统课程设计

    进程调度算法是操作系统课程设计的重要组成部分,本文通过优先权法与轮转调度算法的模拟,加深对进程概念和进程调度过程的理解,掌握进程状态之间的切换,同时掌握进程调度算法的实现方法和技巧。 一、进程调度算法...

    进程调度设计与实现

    1、 综合应用下列知识点设计并实现操作系统的进程调度:邻接表,布尔数组,非阻塞输入,图形用户界面GUI,进程控制块,进程状态转换,多级反馈队列进程调度算法。 2、 加深理解操作系统进程调度的过程。 3、 加深...

    单处理系统的进程调度

    然后完成进程创建原语和进程调度原语;最后编写主函数对所作工作进程测试。 4.提示与讲解 这个实验主要要考虑三个问题:如何组织进程、如何创建进程和如何实现处理器调度。 考虑如何组织进程,首先就要设定...

    使用动态优先权的进程调度算法的模拟

    【动态优先权的进程调度算法】是...这个实验通过模拟动态优先权调度,有助于学生理解和掌握进程调度的原理,以及如何用编程语言实现这些概念。在VC++环境下,可以使用类似的方法编写并运行代码,以观察和分析调度行为。

    单处理机进程调度实验

    单处理机进程调度实验是操作系统设计的一部分,旨在通过实现单处理器系统的进程调度来加深对进程概念的理解和操作系统中进程的组织、创建和调度等方法的理解。实验要求采用时间片轮转法调度策略,编写程序完成单...

    操作系统短作业优先进程调度算法

    短作业优先进程调度算法是一种在批处理系统中常用的调度策略,其目的是为了提高系统的吞吐量和响应速度,通过优先选择运行时间较短的任务进行执行,从而减少等待时间较长的进程数量。这种算法特别适用于具有大量短...

    c语言 进程调度算法

    通过优先权法和轮转调度算法的模拟,加深对进程概念和进程调度过程的理解,掌握进程状态之间的切换,同时掌握进程调度算法的实现方法和技巧。 二、实验内容 1. 使用C语言或C++语言来实现对N个进程采用优先算法以及...

    进程调度算法模拟

    一个简单的进程调度算法,模拟OS中的进程调度过程 进程标识数:ID 进程优先数:PRIORITY(优先数越大,优先级越高) 进程已占用时间片:CPUTIME,每得到一次调度,值加1; 进程还需占用时间片:ALLTIME,每得到...

    单处理器系统的进程调度+操作系统(c语言版)

    单处理器系统的进程调度是操作系统中的一项重要功能,其目的是为了在单处理器系统中管理和调度多个进程,以提高系统的效率和性能。本文将详细介绍单处理器系统的进程调度算法和实现方法。 进程控制块(PCB)是进程...

    可强占的优先进程调度算法

    综上所述,理解和实现可强占的优先进程调度和循环轮转调度算法,对于优化系统性能、提高用户满意度具有重要意义。同时,合理的PCB设计和就绪队列管理是实现这些算法的关键。通过结合不同的调度策略,可以根据系统...

    操作系统进程调度c++程序

    这个格式对应于进程调度中的关键信息——进程标识(Process ID, PID)和进程执行所需的CPU时间( Burst Time)。在实现时间片轮转法的C++程序时,我们可以使用结构体来存储这些信息,例如: ```cpp struct Process ...

    进程调度的设计与实现

    1、 综合应用下列知识点设计并实现操作系统的进程调度:邻接表,布尔数组,非阻塞输入,图形用户界面GUI,进程控制块,进程状态转换,多级反馈队列进程调度算法。 2、 加深理解操作系统进程调度的过程。 3、 加深...

    UNIX进程调度详解

    时钟中断的发生标志着一个时间周期的结束,触发了一系列与进程调度相关的操作。主要包括: - 更新当前进程的CPU使用统计信息; - 执行调度相关的任务,如重新计算优先级和处理时间片到期; - 发送超时信号给超出CPU...

    实验一进程调度 (1).doc

    3. **设计进程调度算法**:实现一个基于动态优先数和时间片轮转的调度算法。具体步骤如下: - 每次调度时,选择ALLTIME不为0且PRIORITY最大的进程运行一个时间片。 - 进程运行完成后,其优先数减3。 - 更新进程的...

    课程设计 进程调度算法

    根据给定文件的信息,我们可以详细地探讨一下课程设计中关于进程调度算法的知识点。 ...通过这些知识点的学习和实践,学生可以更加深入地理解进程调度算法的工作原理及其在实际操作系统中的应用。

Global site tag (gtag.js) - Google Analytics