我为什么得到'public_stream! = nullptr'执行错误,即使我已经成功地使用'fopen_s'来读取文件?

问题描述 投票:-1回答:1

我在研究操作系统时正在编写调度算法。

并且'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;
}



c file operating-system pthreads fopen
1个回答
0
投票

除了注释中提到的所有问题:

 if (fpp = NULL)

NULL分配给ffp,而不是对其进行比较。你的意思是>

if (fpp == NULL)
© www.soinside.com 2019 - 2024. All rights reserved.