具体来说,就是我想知道:
- 如果优先级一样,那么当线程A由于在等待某个锁而进入阻塞时,如果此时线程B在运行的过程中释放了这个锁,那么线程A会马上抢占B的运行吗? 答案是不会,除非B自己阻塞或运行完毕。
- 如果A的优先级比较高,那么A会抢占B吗? 会的
测试代码:
运行命令:
sudo ./main FIFO 1 1 3 1
最后面一个1,表示只有一个cpu来运行这个测试
前面两个1 表示线程1 和 2 的优先级
线程3 没用到,这里不管。
#define _GNU_SOURCE //for CPU_ZERO CPU_SET
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include <sched.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
long counter = 1000000;
long sum = 0;
int policy;
int policy;
int prio[3];
pthread_attr_t attr;
pthread_t thread1, thread2, thread3;
pthread_barrier_t barrier;
struct sched_param param[3];
sem_t mutex,mutex2;
int cpunum;
void *test_func(void *id) {
int count = 0;
int my_policy, my_id;
char polstr[128];
int i;
my_id = *(int*) id;
struct sched_param param;
//获取线程绑定cpu
cpu_set_t cpuset;
if (pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t),&cpuset) == 0){
for (i=0; i<cpunum; i++) {
if (CPU_ISSET(i, &cpuset)){
printf("%d : CPU %d\n", my_id, i);
}
}
}
if(my_id == 1){
sem_wait(&mutex);
printf("thread 1 get the lock\n");
}
if(my_id == 2){
sem_wait(&mutex2);
printf("thread 2 get the lock\n");
}
// 设置所有线程从此点开始执行
int rc = pthread_barrier_wait(&barrier);
if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD)
{
printf("[%d] Could not wait on barrier\n", my_id);
return (void*) NULL;
}
if (policy == SCHED_OTHER) {
nice(prio[my_id-1]);
}
// 显示线程的调度策略和优先级
pthread_getschedparam(pthread_self(), &my_policy, ¶m);
if (my_policy == SCHED_FIFO) {
strcpy(polstr, "FIFO");
} else if (my_policy == SCHED_RR) {
strcpy(polstr, "RR");
} else if (my_policy == SCHED_OTHER) {
strcpy(polstr, "OTHER");
}
else
strcpy(polstr, "Unkown");
if (my_policy != SCHED_OTHER){
printf("thread %d: scheduled at %s, priority %d\n",
my_id, polstr, param.sched_priority);
}else{
printf("thread %d: scheduled at %s, nice %d\n",
my_id, polstr, prio[my_id-1]);
}
if(my_id == 2){
sem_post(&mutex2);
printf("thread 2 release lock\n");
//sem_wait(&mutex);
for(int i=0;i<100000;++i){}
printf("thread 2 get lock and exit\n");
//sem_post(&mutex);
}
if(my_id == 1){
printf("thread 1 waiting for lock\n");
sem_wait(&mutex2);
for(int i=0;i<100000;++i){}
printf("thread 1, finished caculate.\n");
sem_post(&mutex);
printf("thread 1, release lock\n");
}
return NULL;
}
int main(int argc, char **argv){
int id_1 =1, id_2=2, id_3=3, sch_min, sch_max, onecpu=1;
if (argc !=6 ){
printf("Usage: %s <schedule-policy> <td-1-pri> <td-2-pir> <td-3-pri>\n",
argv[0]);
printf(" schedule-policy = FIFO | RR | OTHER\n");
printf(" td-?-pri = integer\n");
printf(" if policy == OTHER td-?-pri is a nice number\n");
printf(" Otherwise: td-?-pri is between min and max of allowed prios\n");
return 0;
}
if (!strcmp(argv[1], "RR")) {
policy = SCHED_RR;
}
else if (!strcmp(argv[1], "FIFO")) {
policy = SCHED_FIFO;
}
else
policy = SCHED_OTHER;
//获取当前调度策略优先级最大最小值
sch_max= sched_get_priority_max(policy);
sch_min= sched_get_priority_min(policy);
printf("Scheduling policy %s max = %d, min = %d\n\n", argv[1], sch_max, sch_min);
fflush(stdout);
cpunum = sysconf(_SC_NPROCESSORS_CONF);
printf("CPU NUM = %d\n", cpunum);
cpu_set_t mask;
CPU_ZERO(&mask);
// 仅在一个cpu上运行
if (!strcmp(argv[5], "1")) {
CPU_SET(0, &mask);
}
else {
int i;
for (i=0;i<cpunum;i++){
CPU_SET(i, &mask);
}
}
if (sched_setaffinity (0, sizeof (mask), &mask) == -1)
{
printf ("warning: could not set CPU affinity, continuing.../n");
return 1;
}
//初始化barrier变量使线程到达同一点开始运行
if (pthread_barrier_init(&barrier, NULL, 3)) {
printf("Count not create barrier\n");
return 1;
}
sem_init (&mutex, 0, 1);
sem_init (&mutex2, 0, 1);
prio[0] = param[0].sched_priority = atoi (argv[2]);
prio[1] = param[1].sched_priority = atoi (argv[3]);
prio[2] = param[2].sched_priority = atoi (argv[4]);
//设置线程属性
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_attr_setschedpolicy(&attr, policy);
//注意这里要设置PTHREAD_EXPLICIT_SCHED ,默认为PTHREAD_INHERIT_SCHED
//将集成创建者的调度策略
pthread_attr_setinheritsched (&attr, PTHREAD_EXPLICIT_SCHED);
//设置优先级进行开始运行
pthread_attr_setschedparam (&attr, ¶m[0]);
pthread_create(&thread1, &attr, test_func, (void*)&id_1);
pthread_attr_setschedparam (&attr, ¶m[1]);
pthread_create(&thread2, &attr, test_func, (void*)&id_2);
pthread_attr_setschedparam (&attr, ¶m[2]);
pthread_create(&thread3, &attr, test_func, (void*)&id_3);
pthread_exit(NULL);
return 0;
}