【问题标题】:Pthread Scheduling policy and priorityPthread 调度策略和优先级
【发布时间】:2016-01-22 07:49:24
【问题描述】:

我有四个线程正在等待条件变量,当所有四个线程都在等待时,第五个线程发布条件变量。当我将线程优先级设置为 99 的最大值时,线程切换需要很长时间,这远远不能接受。任何人都可以看看并告诉发生了什么吗?

#define N_WORK_THREADS        4
pthread_mutex_t count_mutex     = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  condition_var   = PTHREAD_COND_INITIALIZER;

void *functionCount1(void * arg);
void *functionCount2(void * arg);

int  count = 0;
int  valid = 0;
int thread_personal[N_WORK_THREADS];

static int display_thread_sched_attr(int id)
{
  int policy, s;
  struct sched_param param;

  s = pthread_getschedparam(pthread_self(), &policy, &param);
  if (s != 0) { printf("pthread_getschedparam"); return 1; }

  printf("Thread Id=%d policy=%s, priority=%d\n",id,
          (policy == SCHED_FIFO)  ? "SCHED_FIFO" : (policy == SCHED_RR)    ? "SCHED_RR" : (policy == SCHED_OTHER) ? "SCHED_OTHER" : "???",
          param.sched_priority);

  return 0;
}


int main(void)
{
  pthread_t       thread_work[N_WORK_THREADS];
  pthread_t       thread;
  int             i,s;
  pthread_attr_t  attr;
  struct          sched_param param;

  s = pthread_attr_init(&attr);
  if (s != 0) { printf("pthread_attr_init"); return 1; }

  s = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
  if (s != 0) { printf("pthread_attr_setinheritsched"); return 1; } 

  s = pthread_attr_setschedpolicy(&attr, SCHED_RR);
  if (s != 0) { printf("pthread_attr_setschedpolicy"); return 1; }

  param.sched_priority = 99;
  s = pthread_attr_setschedparam(&attr, &param);
  if (s != 0) { printf("pthread_attr_setschedparam"); return 1; }

  for (i=0; i<N_WORK_THREADS; i++) { thread_personal[i] = 0; }

  for (i=0; i<N_WORK_THREADS; i++) { pthread_create( &thread_work[i], &attr, &functionCount1, (void *)i); }

  param.sched_priority = 99;
  s = pthread_attr_setschedparam(&attr, &param);
  if (s != 0) { printf("pthread_attr_setschedparam"); return 1; }
  pthread_create( &thread, &attr, &functionCount2, (void *)N_WORK_THREADS);

  for (i=0; i<N_WORK_THREADS; i++) { pthread_join( thread_work[i], NULL); }
  pthread_join( thread, NULL);

  for (i=0; i<N_WORK_THREADS; i++) { printf("Thread Id=%d Mutex USed=%d\n",i,thread_personal[i]); }

  exit(EXIT_SUCCESS);
}

void *functionCount1(void * arg)
{
  int i;
  int id = (int) arg;

  display_thread_sched_attr(id);

  for(i=0; i<10; i++)
  {
    pthread_mutex_lock( &count_mutex );

    thread_personal[id] += 1;

    while (((count>>id) & 0x1) == 0)
    {
      pthread_cond_wait( &condition_var, &count_mutex );
    }
    count = count^ (1<<id);

    printf("Thread Id %d: Valid = %d\n",id,valid);

    pthread_mutex_unlock( &count_mutex );
  }

  return NULL;
}

void *functionCount2(void * arg)
{
  int check;
  int id = (int) arg;

  display_thread_sched_attr(id);

  check =0;
  while (check < 10)
  {    
    pthread_mutex_lock( &count_mutex );

    if (count == 0)
    {
      pthread_cond_broadcast ( &condition_var );
      count =0xF;
      printf("Thread Id %d: Counter = %d\n",id,check);
      valid = check++;
    }

    pthread_mutex_unlock( &count_mutex );
  }
  return NULL;
}

【问题讨论】:

  • 您使用什么平台和工具?除非我注释掉所有调度策略配置代码,否则该程序对我根本不起作用(线程不打印输出)。我正在使用 gcc 版本 4.8.4 在 Linux 3.16.0 x86_64 上进行测试。
  • Linux 3.14、gcc 4.8.3 在 armv7 平台上。

标签: multithreading pthreads real-time


【解决方案1】:

我无法在启用调度策略代码的情况下测试您的程序,因为该程序在其中时根本无法工作(正如我在评论中提到的:Linux 3.16.0 x86_64 with gcc 4.8.4)。

但我猜你的问题可能是由于functionCount2() 中的循环:

while (check < 10)
{    
    pthread_mutex_lock( &count_mutex );

    if (count == 0)
    {
      pthread_cond_broadcast ( &condition_var );
      count =0xF;
      printf("Thread Id %d: Counter = %d\n",id,check);
      valid = check++;
    }

    pthread_mutex_unlock( &count_mutex );
}

一般来说,pthreads 中互斥对象的获取不能保证是公平的或 FIFO 的(虽然老实说,我不确定线程​​调度策略会如何影响它)。我相信正在发生的是,这个循环释放count_mutex 然后立即重新获取它,即使其他线程被阻塞等待声明互斥锁。并且在调度策略到位的情况下,这可能会在线程使用其量程之前发生。

【讨论】:

  • 我怀疑任何线程都在使用它的量子,但是你指向 functionCount2() 吗?为什么它不能在 functionCount1() 中发生?你的观点是正确的,因为我计算了 functionCount2() 获得的互斥量,并且计数以数千为单位......
  • 我现在得到了你的品脱,你是绝对正确的。 functionCount2() 一次又一次地获取互斥锁,这导致了问题。我在互斥锁请求和问题消失之前添加了一点睡眠。非常感谢....您能否建议调度策略和优先级对这个问题的影响?当我更改使用 functionCount2() 的线程的优先级时,我注意到不同的行为。
  • 抱歉,关于调度策略我不能说太多——我只是没有机会使用它。我所知道的只是文档所说的基础知识。另外,正如我所指出的,当我尝试从您的示例中使用它时,事情根本不起作用。我没有机会做任何深入的调试。
猜你喜欢
  • 1970-01-01
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多