【发布时间】:2021-09-14 20:36:25
【问题描述】:
对于一个作业,我需要使用sched_yield() 来同步线程。我知道互斥锁/条件变量会更有效,但我不允许使用它们。
我们被允许使用的唯一函数是sched_yield()、pthread_create() 和pthread_join()。我们不能使用互斥锁、锁、信号量或任何类型的共享变量。
我知道sched_yield() 应该放弃对该线程的访问,以便另一个线程可以运行。所以它应该将它执行的线程移到运行队列的后面。
下面的代码应该按顺序打印'abc',然后在所有三个线程都执行后换行。我在函数b() 和c() 中循环了sched_yield(),因为它没有按我预期的那样工作,但我很确定所做的只是延迟打印,因为函数运行了很多次,而不是因为@ 987654330@ 正在工作。
它需要运行的服务器有 16 个 CPU。我在某处看到sched_yield() 可能会立即将线程分配给新的 CPU。
基本上我不确定如何仅使用 sched_yield() 来同步这些线程,因为我可以找到所有在线问题并进行故障排除。
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sched.h>
void* a(void*);
void* b(void*);
void* c(void*);
int main( void ){
pthread_t a_id, b_id, c_id;
pthread_create(&a_id, NULL, a, NULL);
pthread_create(&b_id, NULL, b, NULL);
pthread_create(&c_id, NULL, c, NULL);
pthread_join(a_id, NULL);
pthread_join(b_id, NULL);
pthread_join(c_id, NULL);
printf("\n");
return 0;
}
void* a(void* ret){
printf("a");
return ret;
}
void* b(void* ret){
for(int i = 0; i < 10; i++){
sched_yield();
}
printf("b");
return ret;
}
void* c(void* ret){
for(int i = 0; i < 100; i++){
sched_yield();
}
printf("c");
return ret;
}
【问题讨论】:
-
除非您为线程/进程使用实时调度程序算法,否则
sched_yield()未指定,如手册页所述。从设置适当的调度程序开始,这样您就可以从屈服中获得可预测的行为。 -
@Shawn 会怎么做呢?我们被告知只需添加线程并同步它们,所以我不知道它会变得更加复杂
-
假设您使用的是 Linux,请以 man7.org/linux/man-pages/man7/sched.7.html 开头
-
如果您被告知使用
sched_yield()而之前没有讨论调度算法及其适用的算法,那么这对您的班级或教师的质量来说并不好。 -
顾名思义,
sched_yield()是关于线程调度,而不是同步。它不是同步对象(例如互斥锁)的合适替代品。