我在研究操作系统时正在编写调度算法。
并且'fopen_s'用于从'txt'文件接收有关该过程的信息。
[首先,我用'errno_t'检查了函数的输出,并且'0'正常。
但是,如果我尝试执行它,则会出现诸如图像之类的错误,并且无法继续进行。错误发生在哪里?
此代码是使用c语言在Visual Studio 2017中编写的。
这是'process.txt'。 (都是整数。)
1 1 0 10 3
1 2 0 1 1
1 3 0 2 4
1 4 0 5 2
2 5 0 5 2
2 6 0 4 3
2 7 0 1 2
2 8 0 7 1
3 9 0 5 2
3 10 0 4 3
3 11 0 1 4
3 12 0 6 1
这是导致错误的核心代码。
int main()
{
sem_init(&semaphore, 0, 1);
q1 = (Process *)malloc(sizeof(Process) * 100);
q2 = (Process *)malloc(sizeof(Process) * 100);
q3 = (Process *)malloc(sizeof(Process) * 100);
FILE *fpp = NULL;
errno_t err = fopen_s(&fpp, "sample.txt", "r");
if (fpp = NULL)
{
printf("OPEN ERROR\n");
return 0;
}
while (!feof(fpp))
{
fscanf_s(fpp, "%d %d %d %d %d",
&class_num, &sub_id, &sub_arrive_time, &sub_burst, &sub_priority);
if (class_num == 1)
{
q1[i_q1].id = sub_id;
q1[i_q1].arrive_time = sub_arrive_time;
q1[i_q1].burst = sub_burst;
q1[i_q1].priority = sub_priority;
i_q1++;
}
else if (class_num = 2)
{
q2[i_q2].id = sub_id;
q2[i_q2].arrive_time = sub_arrive_time;
q2[i_q2].burst = sub_burst;
q2[i_q2].priority = sub_priority;
i_q2++;
}
else if (class_num = 3)
{
q3[i_q3].id = sub_id;
q3[i_q3].arrive_time = sub_arrive_time;
q3[i_q3].burst = sub_burst;
q3[i_q3].priority = sub_priority;
i_q3++;
}
p_count++;
}//초기화 완료
pthread_create(&thread[idx], NULL, MLQS, NULL);//별도의 함수 만들어서 넣기
pthread_join(thread[idx], NULL);
fclose(fpp);
free(q1);
free(q2);
free(q3);
system("pause");
return 0;
}
这是完整的代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <pthread.h>
#include <semaphore.h>
#define TRUE 1
#define FALSE 0
typedef struct _process {
int id;
int arrive_time;
int waiting_time;
int return_time;
int turnaround_time;
int response_time;
int burst;
int priority;
int completed;
}Process;
//쓰레드 동기화를 동기화를 위한 semaphore
sem_t semaphore;
int process_count = 0;
int p_count = 0;
int i_q1 = 0;
int i_q2 = 0;
int i_q3 = 0;
int class_num;
int sub_id;
int sub_arrive_time;
int sub_burst;
int sub_priority;
Process *q1;
Process *q2;
Process *q3;
int idx = 0;
pthread_t thread[5];
int time_quantum = 2;
//프로세스 초기화
void p_init(Process p[], int length)
{
int i;
for (i = 0; i < length; i++)
{
p[i].waiting_time = 0;
p[i].return_time = 0;
p[i].response_time = 0;
p[i].completed = FALSE;
}
}
int all_completed(Process *p1, Process *p2, Process *p3, int q1_len, int q2_len, int q3_len)
{
int i;
for (i = 0; i < q1_len; i++)
{
if (p1[i].completed == FALSE)
return FALSE;
}
for (i = 0; i < q2_len; i++)
{
if (p2[i].completed == FALSE)
return FALSE;
}
for (i = 0; i < q2_len; i++)
{
if (p3[i].completed == FALSE)
return FALSE;
}
return TRUE;
}
void print_table(Process p[], int n)
{
int i;
// 반복문에서 사용할 변수 선언
puts("\t+-----+------------+-------------+----------+-------------+-----------------+--------------+-----------------+");
puts("\t| PID | Burst Time | Arrive Time | Priority | Return Time | Response Time | Waiting Time | Turnaround Time |");
puts("\t+-----+------------+-------------+----------+-------------+-----------------+--------------+-----------------+");
/* 프로세스 갯수만큼 반복하며 포맷을 맞추어 출력 */
for (i = 0; i < n; i++)
{
printf("\t| %3d | %3d | %3d | %3d | %3d | %3d | %3d | %3d |\n",
p[i].id, p[i].burst, p[i].arrive_time, p[i].priority, p[i].return_time, p[i].response_time, p[i].waiting_time, p[i].turnaround_time);
puts("\t+-----+------------+-------------+----------+-------------+-----------------+--------------+-----------------+");
}
puts("\n");
}
// 반환 시간을 비교하는 함수
int compare_by_return_time(const void *a, const void *b)
{
Process *pA = (Process *)a;
Process *pB = (Process *)b;
/* pA의 반환 시간이 작을 경우 */
if (pA->return_time < pB->return_time)
return -1;
/* ptA의 반환 시간이 클 경우 */
else if (pA->return_time > pB->return_time)
return 1;
/* 반환 시간이 같을 경우 -> 존재 X */
else
return 0;
}
// 반환 시간을 퀵 소트 기반으로 정렬한다.
void quick_sort_by_return_time(Process p[], int len)
{
qsort(p, len, sizeof(Process), compare_by_return_time);
}
// 우선 순위를 비교하는 함수
int compare_by_priority(Process *a, Process *b)
{
Process *pA = (Process *)a;
Process *pB = (Process *)b;
if (a->priority == b->priority) {
if (a->burst != b->burst) {
if (a->burst < b->burst)
return -1;
else
return 1;
}
else
return 0;
}
else {
if (a->priority < b->priority)
return -1;
else if (a->priority > b->priority)
return 1;
}
}
void quick_sort_by_priority_time()
{
qsort(q1, i_q1, sizeof(Process), compare_by_priority);
}
void gantt_chart(Process p[], int len)
{
int i, j; // 반복문에 사용할 변수
printf("\t ");
for (i = 0; i < len; i++)
{
for (j = 0; j < p[i].burst; j++)
printf("--");
printf(" ");
}
printf("\n\t|");
for (i = 0; i < len; i++)
{
for (j = 0; j < p[i].burst - 1; j++)
printf(" ");
printf("%d", p[i].id);
for (j = 0; j < p[i].burst - 1; j++)
printf(" ");
printf("|");
}
printf("\n\t ");
for (i = 0; i < len; i++)
{
for (j = 0; j < p[i].burst; j++)
printf("--");
printf(" ");
}
printf("\n\t");
printf("0");
for (i = 0; i < len; i++)
{
for (j = 0; j < p[i].burst; j++)
printf(" ");
if (p[i].return_time > 9)
printf("\b");
printf("%d", p[i].return_time);
}
printf("\n");
}
//**************************************************//
// Q1 : Non-preemptive Priority Scheduling Algorithm
// 알고리즘 시간 계산 함수
void Cal_for_npps(Process p[], int len)
{
int i, j; // 반복문에 사용할 변수
int check; // 모든 프로세스 완료 여부 확인
int min; // Priority가 가장 높은 index 저장
int time = 0; // 현재 시간
p[0].return_time = p[0].burst;
p[0].turnaround_time = p[0].return_time - p[0].arrive_time;
p[0].response_time = 0;
p[0].completed = TRUE;
time = p[0].burst;
while (TRUE)//모든 프로세스 완료 시 종료
{
min = INT_MAX;
check = FALSE;
for (i = 1; i < len; i++)//Priority가 가장 높은 프로세스 탐색
{
if ((p[min].priority > p[i].priority) && (p[i].completed == FALSE))
{//현재 Priority보다 작은 Priority 가졌지만 실행되지 않았다면 갱신
min = i;
check = TRUE;
}
}
if (check == FALSE)//모든 프로세스 완료 시 반복문 탈출
break;
p[min].response_time = time - p[min].arrive_time;
p[min].return_time = time + p[min].burst;
p[min].turnaround_time = p[min].return_time - p[min].arrive_time;
p[min].waiting_time = time - p[min].arrive_time;
p[min].completed = TRUE;
time += p[min].burst;
}
}
void *NPPS(void *arg)
{
int i; // 반복문에 사용할 변수
int total_waiting_time = 0;
int total_turnaround_time = 0;
int total_response_time = 0;
p_init(q1, i_q1);
quick_sort_by_priority_time();
Cal_for_npps(q1, i_q1);
for (i = 0; i < i_q1; i++)
{
total_waiting_time += q1[i].waiting_time;
total_turnaround_time += q1[i].turnaround_time;
total_response_time += q1[i].response_time;
}
quick_sort_by_return_time(q1, i_q1);
printf("\tNon-preemptive Priority Scheduling Algorithm\n\n");
gantt_chart(q1, i_q1);
printf("\n\tAverage Waiting Time : %-2.2lf\n", (double)total_waiting_time / (double)i_q1);
printf("\tAverage Turnaround Time : %-2.2lf\n", (double)total_turnaround_time / (double)i_q1);
printf("\tAverage Response Time : %-2.2lf\n\n", (double)total_response_time / (double)i_q1);
print_table(q1, i_q1);
}
//**************************************************//
// Q2 : HRN(Highest Response-Ratio Next)
void *HRN(void *arg)
{
int i, j; // 반복문에 사용할 변수
int time, locate; // 현재 시간과 프로세스 위치
int total_burst_time = 0;
int total_waiting_time = 0;
int total_turnaround_time = 0;
int total_response_time = 0;
float hrr, temp; // 우선순위 저장
p_init(q2, i_q2);
for (i = 0; i < i_q2; i++)
{
total_burst_time += q2[i].burst;
}
for (time = q2[0].arrive_time; time < total_burst_time;)
{
hrr = -99999;
for (i = 0; i < i_q2; i++)// Priority가 가장 높은 프로세스 탐색
{
if (q2[i].completed != TRUE)
{
temp = (q2[i].burst + (time - q2[i].arrive_time)) / q2[i].burst;
if (hrr < temp)//우선순위 갱신
{
hrr = temp;
locate = i;
}
}
}
time += q2[locate].burst;
q2[locate].waiting_time = time - q2[locate].arrive_time - q2[locate].burst;
q2[locate].turnaround_time = time - q2[locate].arrive_time;
q2[locate].return_time = q2[locate].turnaround_time + q2[locate].arrive_time;
q2[locate].response_time = q2[locate].waiting_time;
q2[locate].completed = TRUE;
total_waiting_time += q2[locate].waiting_time;
total_turnaround_time += q2[locate].turnaround_time;
total_response_time += q2[locate].response_time;
}
quick_sort_by_return_time(q2, i_q2);
printf("\tHighest Response Ratio Next Scheduling Algorithm\n\n");
gantt_chart(q2, i_q2);
printf("\n\tAverage Waiting Time : %-2.2lf\n", (double)total_waiting_time / (double)i_q2);
printf("\tAverage Turnaround Time : %-2.2lf\n", (double)total_turnaround_time / (double)i_q2);
printf("\tAverage Response Time : %-2.2lf\n\n", (double)total_response_time / (double)i_q2);
print_table(q2, i_q2);
}
void cal_for_sjf(Process *p, int len)
{
int i, j; // 반복문에 사용할 변수
int cur_time = 0; // 현재 시간
int min = 0; // 최소 시간을 갖는 인덱스 저장
p[0].completed = TRUE;
p[0].return_time = p[0].burst;
p[0].turnaround_time = p[0].burst - p[0].arrive_time;
p[0].waiting_time = 0;
cur_time = p[0].burst;
for (i = 1; i < len; i++)
{
for (j = 1; j < len; j++)
{
if (p[j].completed == TRUE)
continue;
else
{
min = j;
break;
}
}
for (j = 1; j < len; j++)
{
if ((p[j].completed == FALSE) && (p[j].burst < p[min].burst))
{
min = j;
}
}
p[min].waiting_time = cur_time - p[min].arrive_time;
p[min].completed = TRUE;
cur_time += p[min].burst;
p[min].return_time = cur_time;
p[min].turnaround_time = p[min].return_time - p[min].arrive_time;
}
}
void *SJF(void *arg)
{
int i;
int total_waiting_time = 0;
int total_turnaround_time = 0;
int total_response_time = 0;
p_init(q3, i_q3);
cal_for_sjf(q3, i_q3);
for (i = 0; i < i_q3; i++)
{
q3[i].return_time = q3[i].turnaround_time + q3[i].arrive_time;
q3[i].response_time = q3[i].waiting_time;
total_waiting_time += q3[i].waiting_time;
total_turnaround_time += q3[i].turnaround_time;
total_response_time += q3[i].response_time;
}
printf("\tSJF Scheduling Algorithms\n\n");
quick_sort_by_return_time(q3, i_q3);
gantt_chart(q3, i_q3);
printf("\n\tAverage Waiting Time : %-2.2lf\n", (double)total_waiting_time / (double)i_q3);
printf("\tAverage Turnaround Time : %-2.2lf\n", (double)total_turnaround_time / (double)i_q3);
printf("\tAverage Response Time : %-2.2lf\n\n", (double)total_response_time / (double)i_q3);
print_table(q3, i_q3);
}
void *MLQS(void *arg)
{
idx++;
while (all_completed(q1, q2, q3, i_q1, i_q2, i_q3)) {
sem_wait(&semaphore);
if (idx == 1) {
pthread_create(&thread[idx], NULL, NPPS, NULL);
pthread_join(thread[idx], NULL);
}
else if (idx == 2) {
pthread_create(&thread[idx], NULL, HRN, NULL);
pthread_join(thread[idx], NULL);
}
else if (idx == 3) {
pthread_create(&thread[idx], NULL, SJF, NULL);
pthread_join(thread[idx], NULL);
}
idx++;
sem_post(&semaphore);
if (idx > 3)
idx = 1;
}
}
int main()
{
sem_init(&semaphore, 0, 1);
q1 = (Process *)malloc(sizeof(Process) * 100);
q2 = (Process *)malloc(sizeof(Process) * 100);
q3 = (Process *)malloc(sizeof(Process) * 100);
FILE *fpp = NULL;
errno_t err = fopen_s(&fpp, "sample.txt", "r");
if (fpp = NULL)
{
printf("OPEN ERROR\n");
return 0;
}
while (!feof(fpp))
{
fscanf_s(fpp, "%d %d %d %d %d",
&class_num, &sub_id, &sub_arrive_time, &sub_burst, &sub_priority);
if (class_num == 1)
{
q1[i_q1].id = sub_id;
q1[i_q1].arrive_time = sub_arrive_time;
q1[i_q1].burst = sub_burst;
q1[i_q1].priority = sub_priority;
i_q1++;
}
else if (class_num = 2)
{
q2[i_q2].id = sub_id;
q2[i_q2].arrive_time = sub_arrive_time;
q2[i_q2].burst = sub_burst;
q2[i_q2].priority = sub_priority;
i_q2++;
}
else if (class_num = 3)
{
q3[i_q3].id = sub_id;
q3[i_q3].arrive_time = sub_arrive_time;
q3[i_q3].burst = sub_burst;
q3[i_q3].priority = sub_priority;
i_q3++;
}
p_count++;
}//초기화 완료
pthread_create(&thread[idx], NULL, MLQS, NULL);//별도의 함수 만들어서 넣기
pthread_join(thread[idx], NULL);
fclose(fpp);
free(q1);
free(q2);
free(q3);
system("pause");
return 0;
}
除了注释中提到的所有问题:
if (fpp = NULL)
将NULL
分配给ffp
,而不是对其进行比较。你的意思是>
if (fpp == NULL)