gpt4 book ai didi

c - 信号量无法正常工作

转载 作者:行者123 更新时间:2023-11-30 16:46:18 24 4
gpt4 key购买 nike

我一直在尝试编写一个程序,使用线程和信号量模拟最短优先作业算法。当主线程告诉他这样做时,每个线程都有责任打印其ID。主线程(主)将控制这些作业的时间打印在屏幕上。以下是我想到的,但我似乎做错了一些我还无法弄清楚的事情。我设法让它打印出相应的作业,但总是有 10 个作业中缺少 2 个。文件格式是“id(char)arrival(int)burst(int)”。所以我在这里迫切需要帮助,因为我有尝试了很多事情,但总是在几个小时内陷入同样的​​情况。

#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;

}

最佳答案

我不太理解你的一些计算,但我发现了两个问题。

首先,在函数PrintJob()中,您应该在发布主信号量之前设置jobs[i].done = 1;,因为主线程评估jobs[i].done 来决定唤醒哪个线程。

因此 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]].done 设置为1。我不确定这是主要问题,但当 jobs[index[0]].burst 为最小值时,您似乎忘记给 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]);

}

关于c - 信号量无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43823746/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com