2017-05-06 1 views
0

저는 스레드와 세마포어를 사용하여 최단 퍼스트 작업 알고리즘을 시뮬레이트하는 프로그램을 작성하려고했습니다. 마스터 스레드가 그렇게 지시하면 모든 스레드가 id를 인쇄 할 책임이 있습니다. 마스터 스레드 (주)는 이러한 작업이 화면에 인쇄되는 시점을 제어합니다. 다음은 내가 생각해 냈지만, 나는 뭔가를 잘못하고있는 것 같아서 아직 이해할 수 없다. 나는 그 일을 적절하게 인쇄 할 수 있었지만, 그 중 항상 2는 10.File 형식에서 빠져있다. "ID (char) 도착 (int) 버스트 (int)". 그래서 필자는 여기있는 것처럼 필사적으로 도움이 필요하다. 여러 가지 일을 시도해 왔고 몇 시간 동안 동일한 상황에 처해있었습니다.semaphores가 올바르게 작동하지 않습니다.

#include <stdio.h> 
#include <pthread.h> 
#include <semaphore.h> 
#include <stdlib.h> 
#define MAX 10 

sem_t childs[MAX]; 
sem_t master; 

int jobdone = 0; 

typedef struct job 
{ 
    int burst, arrival, wait_time, turn_around, executed, done; 
    char id; 
} JOB; 

JOB jobs[MAX]; 

void ShortestFirstJob() 
{ 

    int i, j; 
    char id; 
    int burst, arrival, wait_time, turn_around, done; 
    for (i = 0; i < MAX; i++) 
    { 
    for (j = 0; j < MAX - 1; j++) 
    { 
     if (jobs[j].arrival > jobs[j + 1].arrival) 
     { 
     id = jobs[j].id; 
     done = jobs[j].done; 
     burst = jobs[j].burst; 
     arrival = jobs[j].arrival; 
     wait_time = jobs[j].wait_time; 
     turn_around = jobs[j].turn_around; 
     jobs[j].id = jobs[j + 1].id; 
     jobs[j].burst = jobs[j + 1].burst; 
     jobs[j].wait_time = jobs[j + 1].wait_time; 
     jobs[j].arrival = jobs[j + 1].arrival; 
     jobs[j].turn_around = jobs[j + 1].turn_around; 
     jobs[j].done = jobs[j + 1].done; 
     jobs[j + 1].id = id; 
     jobs[j + 1].burst = burst; 
     jobs[j + 1].arrival = arrival; 
     jobs[j + 1].wait_time = wait_time; 
     jobs[j + 1].turn_around = turn_around; 
     jobs[j + 1].done = done; 

     } 
    } 
    } 
    printf("SORT \n"); 
    for (j = 0; j < MAX; j++) 
    { 
    printf("%c %d %d\n", jobs[j].id, jobs[j].arrival, jobs[j].burst); 
    } 

} 

void* PrintJob(void *params) 
{ 

    char id = *((char*) params); 

    int i, j, k; 
    for (i = 0; i < MAX; i++) 
    { 
    if (id == jobs[i].id) 
     break; 
    } 

    for (k = 0; k < jobs[i].burst; k++) 
    { 

    sem_wait(&childs[i]); 
    printf("%c", id); 
    fflush(stdout); 
    jobs[i].executed += 1; 

    for (j = 0; j < MAX; j++) 
    { 
     if ((i != j) && (jobs[j].arrival > 0)) 
     { 
     jobs[j].arrival -= 1; 
     jobs[j].wait_time += 1; 
     } 
    } 

    sem_post(&master); 
    } 

    jobs[i].done = 1; 
    jobdone++; 

} 
int main() 
{ 

    pthread_t threadIds[MAX]; 
    char threadsIdx; 
    int result; 
    int i = 0; 
    int j; 
    int index[MAX]; 

    FILE* fp = fopen("joblist1.txt", "r"); 

    for (j = 0; j < MAX; j++) 
    { 
    sem_init(&childs[j], 0, 0); 
    } 
    sem_init(&master, 0, 1); 

    char id; 
    int arrival, burst; 
    while (fscanf(fp, "%c %d %d\n", &id, &arrival, &burst) != EOF) 
    { 

    jobs[i].id = id; 
    jobs[i].arrival = arrival; 
    jobs[i].burst = burst; 
    jobs[i].wait_time = 0; 
    jobs[i].turn_around = 0; 
    jobs[i].executed = 0; 
    jobs[i].done = 0; 

    i++; 
    } 

    for (j = 0; j < MAX; j++) 
    { 
    printf("%c %d %d\n", jobs[j].id, jobs[j].arrival, jobs[j].burst); 
    } 

    ShortestFirstJob(); 

    for (i = 0; i < MAX; i++) 
    { 

    if (pthread_create(&threadIds[i], NULL, PrintJob, &jobs[i].id) != 0) 
    { 
     perror("thread create"); 
     exit(1); 
    } 
    } 

    int k, c = 0; 
    int min = 0; 
    int in = 0; 
    int value, flag = 0; 
    while (jobdone < MAX) 
    { 

    k = 0; 
    c = 0; 

    sem_wait(&master); 
    for (j = 0; j < MAX; j++) 
    { 
     if ((jobs[j].arrival == 0) && (jobs[j].done != 1)) 
     { 
     index[k++] = j; 
     c++; 

     } 
    } 

    if (c == 1) 
    { 

     sem_post(&childs[index[0]]); 

    } 
    else if (c > 1) 
    { 

     min = jobs[index[0]].burst; 
     for (j = 1; j < k; j++) 
     { 
     if (jobs[index[j]].burst <= min) 
     { 
      min = jobs[index[j]].burst; 
      in = index[j]; 

     } 
     } 

     sem_post(&childs[in]); 

    } 

    } 

    for (i = 0; i < MAX; i++) 
    { 
    pthread_join(threadIds[i], NULL); 
    } 

    return 0; 

} 

답변

0

일부 계산은 잘 이해하지 못했지만 두 가지 문제점이 발견되었습니다.

먼저 PrintJob() 함수에서 주 스레드가 jobs[i].done을 평가하여 깨우는 스레드를 결정하기 때문에 마스터 세마포를 게시하기 전에 jobs[i].done = 1;을 설정해야합니다.

그래서 PrintJob() 함수에 대한 정확한 코드 같아야

void* PrintJob(void *params) { 

    char id = *((char*) params); 

    int i, j, k; 
    for (i = 0; i < MAX; i++) { 
    if (id == jobs[i].id) break; 
    } 

    for (k = 0; k < jobs[i].burst; k++) { 
    sem_wait(&childs[i]); 
    printf("%c", id); 
    fflush(stdout); 
    jobs[i].executed += 1; 

    for (j = 0; j < MAX; j++) 
    { 
     if ((i != j) && (jobs[j].arrival > 0)) 
     { 
     jobs[j].arrival -= 1; 
     jobs[j].wait_time += 1; 
     } 
    } 

    ///////////////////////////// 
    // Here: 
    if(k == (jobs[i].burst - 1)) 
     jobs[i].done = 1; 
     jobdone++; 
    } 
    ///////////////////////////// 

    sem_post(&master); 
    } 
} 

번째 문제는 메인 스레드이다. 정확히 무엇이 문제인지는 모르겠지만 프로그램을 테스트 할 때 문제는 여기에 있었고 메인 스레드는 jobs[index[j]].done1으로 설정된 완료된 스레드를 깨우려고했습니다. 나는 그것이 주된 문제인지는 모르지만, 이 최소 일 때 in에 값을 제공하는 것을 잊어 버린 것처럼 보입니다. 올바른 코드는 다음과 같아야합니다.

else if (c > 1) { 

    min = jobs[index[0]].burst; 

    // Here: 
    in = index[0]; 

    for (j = 1; j < k; j++) 
    { 
    if (jobs[index[j]].burst <= min) 
    { 
     min = jobs[index[j]].burst; 
     in = index[j]; 
    } 
    } 

    sem_post(&childs[in]); 

} 
관련 문제