Tính thời gian quay vòng trung bình, thời gian chờ trung bình cho thuật toán FCFSbằng cách chỉnh sửa bổ sung hàm schedule trong tập tin schedule_FCFS.cYêu cầu 1.2.. Giả sử thời gian đến
Trang 1TRƯỜNG ĐẠI HỌC TÔN ĐỨC THẮNG
KHOA CÔNG NGHỆ THÔNG TIN
BÁO CÁO BÀI TẬP NMHĐH
HK2, 2021-2022
Lab 5 Thành Viên: Nguyễn Ngô Đăng Khoa (521H0084)
Mục lục
1 Lập lịch CPU: 2
2 Bài toán ước lượng giá trị số PI 14
3 Ứng dụng sắp xếp bằng tiểu trình A Code chương trình: 15
KẾT LUẬN 19
Trang 21 Lập lịch CPU:
Yêu cầu 1.1 Tính thời gian quay vòng trung bình, thời gian chờ trung
bình cho thuật toán FCFS
bằng cách chỉnh sửa bổ sung hàm schedule() trong tập tin
schedule_FCFS.c
Yêu cầu 1.2 Giả sử thời gian đến của mỗi tiến trình khác nhau và khác
0 Hãy tiếp tục chỉnh sửa
hàm schedule() trong tập tin schedule_FCFS.c Gợi ý: Trong tập tin schedule_FCFS.c một mảng
các Task đã được dùng để chứa thông tin tiến trình theo thứ tự "First come" Hãy sắp xếp lại mảng
đó với tiêu chí "Arrival Time First", rồi tính toán và xuất ra theo thứ tự mảng.
Yêu cầu 1.3: hiện thực tập tin schedule_priority.c Gợi ý: tương tự yêu
cầu 2, hãy sắp mảng các
Task lại theo tiêu chí "Độ ưu tiên", nếu cùng độ ưu tiên thì dùng tiêu chí phụ là FCFS.
Yêu cầu 1.4: hiện thực tập tin schedule_sjf.c Gợi ý: tương tự yêu cầu 2,
hãy sắp mảng các Task
lại theo tiêu chí "Burst", nếu cùng độ ưu tiên thì dùng tiêu chí phụ là FCFS.
Yêu cầu 1.5: hiện thực tập tin schedule_rr.c Gợi ý: Mảng các Task cần
cập nhật lại Burst của mỗi
tác vụ sau mỗi lần đáp ứng CPU, tác vụ nào có Burst giảm còn 0 thì xóa khỏi mảng Task.
Yêu cầu 1.6: hiện thực tập tin schedule_priority_rr.c Gợi ý: Copy lại Yêu
cầu 3 và bổ sung: nếu
có nhiều tác vụ cùng độ ưu tiên thì sao chép chúng và một Mảng khác
và chạy RR trên mảng đó
A Code chương trình:
/**
* cpu.h
*/
// Độ dài định mức thời gian.
#define QUANTUM 10
// Chạy task được chỉ định cho phần thời gian sau.
void run(Task *task, int start, int slice);
/**
* task.h
* Đại diện cho 1 task trong hệ thống.
*/
#ifndef TASK_H
#define TASK_H
Trang 3// Struct thể hiện task.
typedef struct task {
char *name;
int tid;
int priority;
int burst;
int arrival;
} Task;
#endif
/**
* list.h
* Danh sách cấu trúc dữ liệu chứa các task trong hệ thống.
*/
#include "task.h"
struct node {
Task *task;
struct node *next;
};
// Hoạt động thêm và xóa.
void insert(struct node **head, Task *task);
void delete(struct node **head, Task *task);
void traverse(struct node *head);
Trang 4* schedulers.h
*/
#define MIN_PRIORITY 1
#define MAX_PRIORITY 10
// Thêm 1 task vào danh sách.
void add(char *name, int priority, int arrival, int burst);
// Invoke schedule.
void schedule();
/**
* CPU.c
* CPU “ảo” để theo dõi thời gian hệ thống.
*/
#include <stdio.h>
#include "task.h"
// Chạy task này vào phần thời gian được chỉ định.
void run(Task *task, int start, int slice) {
printf("Running task = [%s] [%d] [%d] [%d] from %d to %d.\n",>name, >priority,
task->arrival, task->burst, start, slice+start);
}
/**
* list.c
* Danh sách các hoạt động khác nhau.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "list.h"
#include "task.h"
// Thêm 1 task mới vào danh sách các task.
void insert(struct node **head, Task *newTask) {
// Thêm task mới vào danh sách.
struct node *newNode = malloc(sizeof(struct node));
newNode->task = newTask;
newNode->next = *head;
*head = newNode;
}
// Xóa task được chọn khỏi danh sách.
Trang 5void delete(struct node **head, Task *task)
{ struct node *temp;
struct node *prev;
temp = *head;
// Trường hợp đặc biệt - đầu danh sách.
if (strcmp(task->name,temp->task->name) == 0) {
*head = (*head)->next;
}
else {
// Phần tử cuối của mảng.
prev = *head;
temp = temp->next;
while (strcmp(task->name,temp->task->name) != 0)
{ prev = temp;
temp = temp->next;
}
prev->next = temp->next;
}
}
// Bỏ qua danh sách.
void traverse(struct node *head)
{ struct node *temp;
temp = head;
while (temp != NULL) {
printf("[%s] [%d] [%d]\n",temp->task->name, temp->task->priority, temp->task->burst); temp = temp->next;
}
}
/**
* Driver.c
* Lịch trong định dạng.
* [name] [priority] [CPU burst] [arrival time]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "task.h"
#include "list.h"
Trang 6#include "schedulers.h"
// Kích thước của mảng char task.
#define SIZE 100
int main(int argc, char *argv[])
{ FILE *in;
char *temp, *name;
char task[SIZE];
int priority, arrival, burst;
// Mở file để đọc với tên là chuỗi đối số truyền vào.
in = fopen(argv[1],"r");
// Vòng lặp lấy chuỗi kí tự cho đến hết file.
while (fgets(task,SIZE,in) != NULL) { temp = strdup(task);
name = strsep(&temp,",");
priority =
atoi(strsep(&temp,",")); arrival =
atoi(strsep(&temp,",")); burst =
atoi(strsep(&temp,","));
// Thêm task vào scheduler dánh sách các task.
add(name,priority,arrival,burst);
// Giải phóng bộ nhớ được cấp phát cho temp.
free(temp);
}
/
**
}
// Đóng file.
fclose(in);
// Invoke the scheduler
schedule();
return 0;
* schedule_fcfs.c
* Lịch trong định dạng.
* [name] [priority] [CPU burst] [arrival time]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "task.h"
#include "cpu.h"
Trang 7#include "schedulers.h"
// Kích thước mảng task.
#define SIZE 100
static int i=0;
Task task[SIZE];
// Thêm 1 task vào danh sách.
void add(char *name, int priority, int arrival, int burst)
{ task[i].name = name;
task[i].burst = burst;
task[i].arrival = arrival;
task[i].priority = priority;
i++;
}
// Invoke scheduler FCFS.
void schedule(){
int j=0;
int time=0;
// Mảng chứa thời gian chờ và thời gian quay vòng.
int wt[SIZE], tt[SIZE];
float awt = 0, att = 0;
// Sắp xếp theo tiêu chí fcfs.
for(j=0;j<i;j++) {
for(int k = j+1;k<i;k++)
{ if(task[j].arrival > task[k].arrival)
{
Task temp = task[j];
task[j] = task[k];
task[k] = temp;
}
}
}
// Chạy task đã được sắp xếp và tình thời gian chờ, thời gian quay vòng.
for(j=0 ; j < i ; j++) {
// Thời gian trống không có task.
if(task[j].arrival > time){
printf("Running task = IDLE from %d to %d.\n",time,task[j].arrival); time=task[j].arrival;
}
wt[j] = time - task[j].arrival;
Trang 8tt[j] = wt[j] + task[j].burst;
awt += wt[j];
att += tt[j];
run(&task[j],time,task[j].burst);
time += task[j].burst;
}
}
/
**
printf("Average waiting time: %f\n", awt / (float) i); printf("Average turnaround time: %f\n", att / (float) i);
* schedule_priority.c
* Lịch trong định dạng.
* [name] [priority] [CPU burst] [arrival time]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "task.h"
#include "cpu.h"
#include "schedulers.h"
// Kích thước mảng task.
#define SIZE 100
static int i=0;
Task task[SIZE];
// Thêm 1 task vào danh sách.
void add(char *name, int priority, int arrival, int burst) { task[i].name = name;
task[i].burst = burst;
task[i].arrival = arrival;
task[i].priority = priority;
i++;
}
// invoke the scheduler
void schedule()
{ int j=0,
k=-1; int time=0;
// Mảng chứa thời gian chờ và thời gian quay vòng.
int wt[SIZE], tt[SIZE];
Trang 9float awt = 0, att = 0;
// Sắp xếp theo priority & tiêu chí fcfs.
for(j=0;j<i;j++) {
for(int k = j+1;k<i;k++) {
// Sắp xếp priority cao nhất lên trước.
if(task[j].priority < task[k].priority)
{ Task temp= task[j];
task[j]=task[k];
task[k]=temp;
}
}
}
for(j=0;j<i;j++) {
for(int k = j+1;k<i;k++) {
// Sắp xếp theo fcfs khi priority bằng nhau.
if((task[j].priority==task[k].priority) && (task[j].arrival > task[k].arrival)) { Task temp = task[j];
task[j]=task[k];
task[k]=temp;
}
}
}
// Sắp xếp task chưa chạy vào thời gian trống.
for(j=0;j<i;j++)
{ if(task[j].arrival > time) {
for (k=j+1; k < i; k++) {
if (task[k].arrival <= time)
{ break;
}
}
Task temp=task[j];
task[j]=task[k];
task[k]=temp;
for(int l=j+1; l<k; l++)
{ Task temp = task[l];
task[l] = task[k];
task[k] = temp;
}
Trang 10time += task[j].burst;
}
// Chạy task đã được sắp xếp và tình thời gian chờ, thời gian quay vòng.
time = 0;
for(j=0 ; j < i ; j++) {
// Thời gian trống không có task.
if(task[j].arrival > time){
printf("Running task = IDLE from %d to %d.\n",time,task[j].arrival); time=task[j].arrival;
}
wt[j] = time - task[j].arrival;
tt[j] = wt[j] + task[j].burst;
awt += wt[j];
att += tt[j];
run(&task[j],time,task[j].burst);
time += task[j].burst;
}
}
/
**
printf("Average waiting time: %f\n", awt / (float) i);
printf("Average turnaround time: %f\n", att / (float) i);
* schedule_sjf.c
* Lịch trong định dạng.
* [name] [priority] [CPU burst] [arrival time]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "task.h"
#include "cpu.h"
#include "schedulers.h"
// Kích thước mảng task.
#define SIZE 100
static int i=0;
Task task[SIZE];
// Thêm 1 task vào danh sách.
void add(char *name, int priority, int arrival, int burst) {
Trang 11task[i].name = name;
task[i].burst = burst;
task[i].arrival = arrival;
task[i].priority = priority;
i++;
}
// invoke the scheduler
void schedule()
{ int j=0,
k=-1; int time=0;
// Mảng chứa thời gian chờ và thời gian quay vòng.
int wt[SIZE], tt[SIZE];
float awt = 0, att = 0;
// Sắp xếp theo priority & tiêu chí fcfs.
for(j=0;j<i;j++) {
for(int k = j+1;k<i;k++) {
// Sắp xếp thời gian làm việc thấp nhất lên trước.
if(task[j].burst > task[k].burst)
{ Task temp= task[j];
task[j]=task[k];
task[k]=temp;
}
}
}
for(j=0;j<i;j++) {
for(int k = j+1;k<i;k++) {
// Sắp xếp theo fcfs khi thời gian làm việc bằng nhau.
if((task[j].burst==task[k].burst) && (task[j].arrival > task[k].arrival)) { Task temp = task[j];
task[j]=task[k];
task[k]=temp;
}
}
}
// Sắp xếp task chưa chạy vào thời gian trống.
for(j=0;j<i;j++)
{ if(task[j].arrival > time) {
for (k=j+1; k < i; k++) {
Trang 12if (task[k].arrival <= time)
{ break;
}
}
Task
temp=task[j];
task[j]=task[k];
task[k]=temp;
for(int l=j+1; l<k; l++)
{ Task temp =
task[l]; task[l] =
task[k]; task[k] =
temp;
}
}
time += task[j].burst;
}
// Chạy task đã được sắp xếp và tình thời gian chờ, thời gian quay vòng.
time = 0;
for(j=0 ; j < i ; j++) {
// Thời gian trống không có task.
if(task[j].arrival > time){
printf("Running task = IDLE from %d to %d.\n",time,task[j].arrival); time=task[j].arrival;
}
wt[j] = time - task[j].arrival;
tt[j] = wt[j] + task[j].burst;
awt += wt[j];
att += tt[j];
run(&task[j],time,task[j].burst);
time += task[j].burst;
}
printf("Average waiting time: %f\n", awt / (float) i);
printf("Average turnaround time: %f\n", att / (float) i);
}
B: Kết Quả Demo
*Theo yêu cầu 1.1 và 1.2:
Trang 13- Lập lịch theo tiêu chí FCFS và tính thời gian chờ trung bình và thời gian quay vòng trung bình:
*Theo yêu cầu 1.3:
- Lập lịch theo Priority, tiêu chí FCFS khi Priority bằng nhau và tính thời gian chờ trung bình và thời gian quay vòng trung bình:
*Theo yêu cầu 1.4:
- Lập lịch theo tiếu chí SJF, tiêu chí FCFS khi thời gian làm công việc bằng nhau và tính thời gian chờ trung bình và thời gian quay vòng trung bình:
Trang 142 Bài toán ước lượng giá trị số PI
A Code chương trình:
#include < stdio.h >
#include < pthread.h >
#include < unistd.h >
#include < sys/types.h >
#include < sys/stat.h >
#include < fcntl.h >
#include < string.h >
#include < stdlib.h >
// S thread t i đa.
#define MAX_THREAD 40
// S đi m t i đa.
#define MAX_POINT 10000
int counter = 0 ;
int in = ; 0
void* count ( void* arg )
{
temp ; int = 0
float x;
float y;
// Ti u trình sinh ra m đi m.
for ( int = i ; i 0 < MAX_POINT;i ++ )
{
x (( = float ) rand () / ( float )(RAND_MAX)) * 2 - 1 ;
y (( = float ) rand () / ( float )(RAND_MAX)) * 2 - 1 ; // Ti u trình c p nh t nh ng đi m n m trong hình tròn.
Trang 15if (x * + * <= x y y ) 1
temp ++ ;
}
in += temp;
counter += MAX_POINT;
}
// Ch ng trình chính.
ươ
int main ()
{
pthread_t threads[MAX_THREAD];
// T o ra n ti u trình.
for int = ( i 0 ;i MAX_THREAD ; i < ++ )
pthread_create ( & threads[i], NULL , & count,( void* )
& counter);
// Đ i n ti u trình tham gia k t thúc.
for int = ( i 0 ; i MAX_THREAD ; i < ++ )
pthread_join (threads[i], NULL );
// Tính và in ra s Pi ố
printf ( "Pi = %f \n double " ,( )in ( / double )counter * 4 );
return ; 0
}
B: Kết Quả Demo
3 Ứng dụng sắp xếp bằng tiểu trình A Code chương trình:
A Code chương trình:
// lab3bai3.c (Merge Sort)
// Ch ng trình áp d ng merge sort s d ng đa lu ng.
#include < stdio.h >
Trang 16#include < pthread.h >
#include < time.h >
#include < stdlib.h >
// S ph n t trong m ng.
#define MAX 20
// S lu ng ố ồ
#define THREAD_MAX 4
int a[MAX];
int part = 0 ;
// Hàm merge cho h p 2 ph n l i v i nhau ợ ầ ạ ớ
void merge ( int low , int mid , int high )
{
ướ // n1 là kích th ử ủ ầồ c c a ph n bên trái và n2 là kích th ướ c
c a ph n bên ph i.
n1 mid low , n2 high mid, i, j; int = - + 1 =
left[n1]; int
right[n2]; int
// L u tr d li u vào ph n bên trái.
for (i ; i n1; i = 0 < ++ )
left[i] a[i low]; = +
// L u tr d li u vào ph n bên ph i.
for (i ; i n2; i = 0 < ++ )
right[i] a[i mid = + + 1 ];
k low; int =
i j ; = = 0
// H p ph n trái và ph i theo th t tăng d n.
while (i n1 < && < j n2)
{
(left[i] if <= right[j])
a[k ++ = ] left[i ++ ];
else
a[k ++ = ] right[j ++ ];
}
// Chèn vào d li u còn l i t ph n trái ữ ệ ạ ừ ầ
while (i n1) <
a[k ++ = ] left[i ++ ];
Trang 17// Chèn vào d li u còn l i t ph n ph i ữ ệ ạ ừ ầ ả
while (j n2) <
a[k ++ = ] right[j ++ ];
}
// Hàm merge sort.
void merge_sort ( int low , int high )
{
// Tính đi m gi a c a m ng ể ữ ủ ả
mid low (high low) ; int = + - / 2
(low high) if <
{
ọ // G i n a ph n đ u ử ầ ầ
merge_sort (low, mid);
ọ // G i n a ph n còn l i ử ầ ạ
merge_sort (mid , high); + 1
ợ // G p 2 ph n l i v i nhau ầ ạ ớ
merge (low, mid, high);
}
}
// Hàm thread
void* thr ( void* arg )
{
ọ // Ch n trong 4 ph n ầ
thread_part part int = ++ ;
// Tính low và high.
low thread_part (MAX int = * / 4 ); high (thread_part int = + 1 ) (MAX ) ; * / 4 - 1
// Tìm đi m gi a ể ữ
mid low (high low) ; int = + - / 2
(low high) if <
{
merge_sort (low, mid);
merge_sort (mid , high); + 1
merge (low, mid, high);
}
}
Trang 1818 // Hàm main.
int main ()
{
// T o m ng v i d li u ng u nhiên.
for int = ( i 0 ; i MAX; i < ++ )
a[i] = rand () % 100 ;
// In ra m ng tr ả ướ c khi s p x p ắ ế
printf ( "Array: " );
for int = ( i 0 ; i MAX; i < ++ )
printf ( " %d " , a[i]);
// Bi n t1, t2 dùng tính th i gian ch y merge sort.
clock_t t1, t2;
t1 = clock ();
pthread_t threads[THREAD_MAX];
// T o 4 lu ng ạ ồ
for int = ( i 0 ; i THREAD_MAX; i < ++ )
pthread_create ( & threads[i], NULL , thr, ( void* ) NULL ); // Đ i t t c các lu ng.
for int = ( i 0 ; i ; i < 4 ++ )
pthread_join (threads[i], NULL );
// G p 4 ph n còn l i.
merge ( 0 , (MAX / 2 - 1 ) , MAX / 2 / 2 - 1 );
merge (MAX , MAX / 2 / 2 + (MAX - - 1 MAX / 2 ) / 2 , MAX - 1 ); merge ( 0 , (MAX - 1 ) / 2 , MAX - 1 );
t2 = clock ();
// Hi n ra màng hình m ng đã đ c s p x p.
printf ( "\nSorted array: " );
for int = ( i 0 ; i MAX; i < ++ )
printf ( " %d " , a[i]);
// Th i gian merge sort ch y tính b ng giây.
printf ( "\nTime taken: %lf \n" , (t2 t1) ( - / double )
(CLOCKS_PER_SEC));
return ; 0
}