使用pthread调度策略和优先级没有任何区别



我正在使用pthread运行一个简单的多线程程序。考虑到使用实际调度程序(SCHED_FIFO策略(,低优先级线程将无法运行,直到高优先级线程完成。但是,当我同时运行这个程序的两个版本(唯一的区别是优先级99->1(时,它们几乎在同一时间完成。我甚至将策略更改为SCHED_OTHER,但仍然没有区别。

# include <stdio.h>
# include <string.h>
# include <pthread.h>
# include <stdlib.h>
# include <unistd.h>
# include <math.h>
# define NUM_THREADS    128
pthread_t tid[NUM_THREADS];
int indexes[NUM_THREADS];
void* dummyThread(void *arg)
{
unsigned long i = 0;
pthread_t id = pthread_self();
float a, b = 5, c = 8;
printf("Thread %d started.n", *(int*)arg + 1);
for(i = 0; i < 10000000; i++)
a = sin(b) + sqrt(b);

printf("Thread %d finished.n", *(int*)arg + 1);
return NULL;
}
int main(void)
{
int i = 0;
pthread_attr_t attr;
struct sched_param schedParam;
struct timespec start, finish;
double elapsed;
pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
schedParam.sched_priority = 1;
pthread_attr_setschedparam(&attr, &schedParam);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
clock_gettime(CLOCK_MONOTONIC, &start);
for (i = 0 ; i < NUM_THREADS; i++)
{
indexes[i] = i;
if (!pthread_create((void*)&tid[i], &attr, &dummyThread, &indexes[i]))
printf("Thread %d created successfully.n", i + 1);

else
printf("Failed to create Thread %d.n", i + 1);
}
for (i = 0 ; i < NUM_THREADS; i++)
pthread_join(tid[i], NULL);
clock_gettime(CLOCK_MONOTONIC, &finish);
elapsed = (finish.tv_sec - start.tv_sec);
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;
printf("%lfn", elapsed);
return 0;
}

编辑1:通过添加pthread_attr_setschedparam和错误检查更新了我的代码。在没有sudo的情况下运行它时,我不会遇到任何错误,并且更改优先级或调度策略仍然不会改变结果。

编辑2:我注意到,当我在同一个进程中创建具有不同优先级的线程时,效果很好。在下面的代码中,对于具有偶数索引的线程,我分配优先级1,而对于具有奇数索引的线程我分配优先级99。它运行良好,奇数线程在偶数线程之前先完成。

# include <stdio.h>
# include <string.h>
# include <pthread.h>
# include <stdlib.h>
# include <unistd.h>
# include <math.h>
# define NUM_THREADS    128
pthread_t tid[NUM_THREADS];
int indexes[NUM_THREADS];
void* dummyThread(void *arg)
{
unsigned long i = 0;
pthread_t id = pthread_self();
float a, b = 5, c = 8;
printf("Thread %d started.n", *(int*)arg);
for(i = 0; i < 10000000; i++)
a = sin(b) + sqrt(b);

printf("Thread %d finished.n", *(int*)arg);
return NULL;
}
int main(void)
{
int i = 0;
pthread_attr_t attr;
struct sched_param schedParam;
struct timespec start, finish;
double elapsed;
clock_gettime(CLOCK_MONOTONIC, &start);
for (i = 0 ; i < NUM_THREADS; i++)
{
indexes[i] = i;
pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
schedParam.sched_priority = i % 2 == 0 ? 1 : 99;
pthread_attr_setschedparam(&attr, &schedParam);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
if (!pthread_create((void*)&tid[i], &attr, &dummyThread, &indexes[i]))
printf("Thread %d created successfully.n", i);

else
printf("Failed to create Thread %d.n", i);
}
for (i = 0 ; i < NUM_THREADS; i++)
pthread_join(tid[i], NULL);
clock_gettime(CLOCK_MONOTONIC, &finish);
elapsed = (finish.tv_sec - start.tv_sec);
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;
printf("%lfn", elapsed);
return 0;
}

由于来自不同进程的线程都被发送到内核中的同一个调度程序,我不知道为什么它不能与不同的进程一起工作。

来自man pthread_attr_setschedpolicy

为了进行由pthread_attr_setschedpolicy((在调用时生效pthread_create(3(,调用方必须使用pthread_attr_setinheritsched(3(设置继承调度程序attr到的attributes对象的属性PTHREAD_EXPLICIT_SCHED。

你忽略了这一点,所以你的SCHED_FIFO没有任何效果。

一旦我添加pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);调用,pthread_create()就开始以EPERM失败(因为只有root可以创建SCHED_FIFO线程(。

相关内容

最新更新