我正在使用障碍来同步我的两个线程,这两个线程将分别执行 task_1 和 task_2 。
在同步之后,我希望优先级较高的任务在优先级较低的任务之前开始执行。
我很惊讶地注意到,即使 task_2 的 更低 优先级高于 task_1 ,有时 task_2 会在 task_1 之前开始执行。
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#define MAX_PRIORITY 99
#define MIN_PRIORITY 1
pthread_t threads[2];
pthread_barrier_t barrier;
void set_priority(int priority, int t_id){
int policy = SCHED_FIFO;
struct sched_param param;
param.sched_priority = priority;
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_setschedparam(pthread_self(), policy, ¶m);
pthread_getschedparam(pthread_self(), &policy, ¶m);
}
int set_core(int core_id) {
int num_cores = sysconf(_SC_NPROCESSORS_ONLN);
if (core_id < 0 || core_id >= num_cores)
return EINVAL;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(core_id, &cpuset);
pthread_t current_thread = pthread_self();
return pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
}
void create_task(int task_number, void *task) {
int rc = pthread_create(&threads[task_number - 1], NULL, task, NULL);
if(rc != 0) {
printf("pthread_create(%d) error %d\n", task_number - 1, rc);
pthread_exit(0) ;
}
}
void schedule_task(int task_number, int priority) {
set_core(2); //running tasks only in 2nd processor core
set_priority(priority, task_number);
}
void start_task_1() {
printf("Task 1 Started \n");
sleep(1); //do task 1
printf("Task 1 Endeded\n");
}
void start_task_2() {
printf("Task 2 Started \n");
sleep(1); //do task 2
printf("Task 2 Endeded\n");
}
void task_1(void *thread_param) {
schedule_task(1, MAX_PRIORITY);
pthread_barrier_wait(&barrier);
start_task_1();
pthread_exit(NULL);
}
void task_2(void *thread_param) {
schedule_task(2, MIN_PRIORITY);
pthread_barrier_wait(&barrier);
start_task_2();
pthread_exit(NULL);
}
int main() {
pthread_barrier_init(&barrier, NULL, 2);
create_task(1, task_1);
create_task(2, task_2);
for (int i = 0; i < 2; i++) {
pthread_join(threads[i], NULL);
}
pthread_barrier_destroy(&barrier);
}
这是POSIX线程中的预期行为吗?如何强制 task_1 始终在 task_2 之前启动?
我正在以root身份执行程序,并确保已相应地设置任务优先级。
答案 0 :(得分:0)
调度取决于OS中使用的调度算法。您正在尝试使用FIFO,只有在启用实时调度时,manpage才可用。
Various "real-time" policies are also supported, for special time- critical applications that need precise control over the way in which runnable threads are selected for execution. For the rules governing when a process may use these policies, see sched(7). The real-time policies that may be specified in policy are: SCHED_FIFO a first-in, first-out policy; and SCHED_RR a round-robin policy.
如果您使用Linux,则在内核编译期间选择调度算法,不确定是否可以在引导期间或动态更改它们。
答案 1 :(得分:0)
您正在创建两个不同的线程,并将它们限制为单独的核心。确实,其中一个具有比另一个更高的优先级设置,但两者都是SCHED_FIFO
个线程,这可能使每个线程在其各自的核心上(至少在用户级别的任务中)是最高优先级的任务。由于每个核心都有一个单独的可运行任务队列,因此调度策略只会影响同一核心上任务之间的比较。
因此,出于所有实际目的,这两项任务实际上具有相同的有效优先级。因此,没有理由期望任务1将在障碍等待之后的任务2之前开始执行。如果你想强制执行(虽然仍然让它们在不同的核心上运行),你需要使用其他一些共享变量让任务1告诉任务2它可以启动。这可能是一个信号量,受互斥锁保护的标志,或者在大多数架构上,只是一个原子更新的标志整数的繁忙循环。