学 生 实 验 报 告
实验课程名称 操作系统
开课实验室
学 院 年级 专业班
学 生 姓 名 学 号
开 课 时 间 2023 至 2024 学年第 二 学期
总 成 绩 | |
教师签名 |
《操作系统》实验报告
开课实验室:DS1502 2024 年 4 月 5 日
学院 | 年级、专业、班 | 姓名 | 成绩 | ||||||||
课程 名称 | 计算机操作系统实验 | 实验项目 名 称 | 线程的调度 | 指导教师 | |||||||
教师评语 | 教师签名: 年 月 日 |
掌握线程的调度(优先级调度) FAQ 二、实验内容 优先级分为静态优先级和动态优先级,静态优先级(nice):内核不会修改它,不随时间而变化,除非用户通过系统调用setpriority进行修改;动态优先级(priority):内核根据线程使用CPU的状况、静态优先级nice和系统负荷计算出来,会随时间而变化。本实验最终的调度依据为调度器只根据动态优先级进行调度。 具体步骤如下:
三、使用仪器、材料 编译器、链接器、调试器 GCC、LD、GDB PC模拟器(虚拟机) Qemu |
|
五、 结论:
| |||
附:main函数所有代码 /* * vim: filetype=c:fenc=utf-8:ts=4:et:sw=4:sts=4 */ #include <inttypes.h> #include <stddef.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <syscall.h> #include <netinet/in.h> #include <stdlib.h> #include "graphics.h" #include "syscall-nr.h" extern void* tlsf_create_with_pool(void* mem, size_t bytes); extern void* g_heap; int tid_foo1, tid_foo2, tid_foo3; typedef struct Numbers { int arr[100]; }MyNumberStruct; int xlen; int ylen; int size = 100; /** * GCC insists on __main * http://gcc.gnu.org/onlinedocs/gccint/Collect2.html */ void __main() { size_t heap_size = 32 * 1024 * 1024; void* heap_base = mmap(NULL, heap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); g_heap = tlsf_create_with_pool(heap_base, heap_size); } void drawsort(int arr[], int flag) { if (flag == 1) { for (int i = 0; i < size; i++) { //line(586, i * 4, 586 + xlen / 3, i * 4, RGB(0, 0, 0)); //line(586, i * 4, 586 + arr[i] * 2.5, i * 4, RGB(255, 255, 255)); line(0, i * 4, xlen / 3, i * 4, RGB(0, 0, 0)); line(0, i * 4, arr[i] * 2.5, i * 4, RGB(0, 0, 255)); } } else if (flag == 2) { for (int i = 0; i < size; i++) { line(300, i * 4, 300 + xlen / 3, i * 4, RGB(0, 0, 0)); line(300, i * 4, 300 + arr[i] * 2, i * 4, RGB(255, 0, 0)); } } } void tsk_foo1(void* pv) // 线程1的冒泡排序 { printf("This is 1 task foo with tid=%d\r\n", task_getid()); tid_foo1 = task_getid(); MyNumberStruct N = (MyNumberStruct)(*((MyNumberStruct*)pv)); struct timespec req, rem; req.tv_sec = 0.9; req.tv_nsec = 1000000L; for (int i = 0; i < size; i++) { for (int j = 0; j < size - i - 1; j++) { if (N.arr[j] > N.arr[j + 1]) { int temp = N.arr[j]; N.arr[j] = N.arr[j + 1]; N.arr[j + 1] = temp; nanosleep(&req, &rem); } } drawsort(N.arr, 1); } drawsort(N.arr, 1); task_exit(0);//不能直接return,必须调用task_exit } void tsk_foo2(void* pv)//线程2的冒泡排序 { printf("This is 2 task foo with tid=%d\r\n", task_getid()); tid_foo2 = task_getid(); MyNumberStruct N1 = (MyNumberStruct)(*((MyNumberStruct*)pv)); struct timespec req, rem; req.tv_sec = 0.9; req.tv_nsec = 1000000L; for (int i = 0; i < size; i++) { for (int j = 0; j < size - i - 1; j++) { if (N1.arr[j] > N1.arr[j + 1]) { int temp = N1.arr[j]; N1.arr[j] = N1.arr[j + 1]; N1.arr[j + 1] = temp; nanosleep(&req, &rem); } } drawsort(N1.arr, 2); } drawsort(N1.arr, 2); task_exit(0);//不能直接return,必须调用task_exit } void tsk_foo3(void* pv) //控制线程 { printf("This is control task foo with tid=%d\r\n", task_getid()); line(80, 450, 100 + 10 * getpriority(tid_foo1), 450, RGB(0, 0, 255)); line(80, 500, 100 + 10 * getpriority(tid_foo2), 500, RGB(255, 0, 0)); while (1) { int key = getchar(); int a = getpriority(tid_foo1); int b = getpriority(tid_foo2); if (key == 0x4800 || key == 0x5000) { if (key == 0x4800) {//up setpriority(tid_foo1, a + 10); a = getpriority(tid_foo1); line(80, 450, 500, 450, RGB(0, 0, 0));//进度条越长,优先级越低 line(80, 450, 100 + 10 * a, 450, RGB(0, 0, 255)); } else { setpriority(tid_foo1, a - 1); a = getpriority(tid_foo1); line(80, 450, 500, 450, RGB(0, 0, 0)); line(80, 450, 100 + 10 * a, 450, RGB(0, 0, 255)); } } else if (key == 0x4d00 || key == 0x4b00) { if (key == 0x4d00) {//right setpriority(tid_foo2, b + 3); b = getpriority(tid_foo2); line(80, 500, 500, 500, RGB(0, 0, 0)); line(80, 500, 100 + 10 * b, 500, RGB(255, 0, 0)); } else { setpriority(tid_foo2, b - 1); b = getpriority(tid_foo2); line(80, 500, 500, 500, RGB(0, 0, 0)); line(80, 500, 100 + 10 * b, 500, RGB(255, 0, 0)); } } else { } } task_exit(0); } /** * 第一个运行在用户模式的线程所执行的函数 */ void main(void* pv) { int mode = 0x115; init_graphic(mode);//进入图形模式 xlen = g_graphic_dev.XResolution; ylen = g_graphic_dev.YResolution; //生成随机数 MyNumberStruct N; for (int i = 0; i < size; i++) { N.arr[i] = rand() % 50 + 1; } MyNumberStruct N1; for (int i = 0; i < size; i++) { N1.arr[i] = rand() % 80 + 1; } //*************************************************************************************************************// //线程函数 unsigned char* stack_foo1; unsigned int stack_size1 = 1024 * 1024; stack_foo1 = (unsigned char*)malloc(stack_size1); //*************************************************************************************************************// //线程函数 unsigned char* stack_foo2; unsigned int stack_size2 = 1024 * 1024; stack_foo2 = (unsigned char*)malloc(stack_size2); //*************************************************************************************************************// unsigned char* stack_foo3; unsigned int stack_size3 = 1024 * 1024; stack_foo3 = (unsigned char*)malloc(stack_size3); //*************************************************************************************************************// tid_foo3 = task_create(stack_foo3 + stack_size3, &tsk_foo3, &N1); setpriority(tid_foo3, 1); tid_foo1 = task_create(stack_foo1 + stack_size1, &tsk_foo1, &N); setpriority(tid_foo1, 3); tid_foo2 = task_create(stack_foo2 + stack_size2, &tsk_foo2, &N1); setpriority(tid_foo2, 3); while (1) ; task_exit(0); free(stack_foo1); free(stack_foo2); free(stack_foo3); } |