线程调度 #包括 #包括 #包括 #定义NUM_线程4 #定义t帐户5 #定义计数限制13 int done=0; 整数计数=0; int thread_id[4]={0,1,2,3}; int thread_runtime[4]={0,5,4,1}; pthread_mutex_t count_mutex; pthread_cond_t count_threshold_cv; void*inc_计数(void*t) { int i; long my_id=(long)t; 长运行时间=线程运行时[my_id]; if(my_id==2&&done==0){ 对于(i=0;i

线程调度 #包括 #包括 #包括 #定义NUM_线程4 #定义t帐户5 #定义计数限制13 int done=0; 整数计数=0; int thread_id[4]={0,1,2,3}; int thread_runtime[4]={0,5,4,1}; pthread_mutex_t count_mutex; pthread_cond_t count_threshold_cv; void*inc_计数(void*t) { int i; long my_id=(long)t; 长运行时间=线程运行时[my_id]; if(my_id==2&&done==0){ 对于(i=0;i,c,multithreading,pthreads,C,Multithreading,Pthreads,SCHED_FIFO和SCHED_RR是实时调度类。它们不用于普通代码中。您应该能够使用pthread互斥体完成大部分需要的操作。SCHED_FIFO和SCHED_RR是实时调度类。它们不用于普通代码中。您应该能够使用pthread完成大部分需要的操作互斥体。如果我正确理解了这个问题,那么您正在尝试生成一种管道,其中下一个线程在上一个线程停止的位置拾取。在这种情况下,最干净的解决方案是使用二进制信号量 假设您有四个线程。创建初始值为{1,0,0,0}的四个信号量。为每个线程分配信号量,并让每个线

SCHED_FIFO和SCHED_RR是实时调度类。它们不用于普通代码中。您应该能够使用pthread互斥体完成大部分需要的操作。

SCHED_FIFO和SCHED_RR是实时调度类。它们不用于普通代码中。您应该能够使用pthread完成大部分需要的操作互斥体。

如果我正确理解了这个问题,那么您正在尝试生成一种管道,其中下一个线程在上一个线程停止的位置拾取。在这种情况下,最干净的解决方案是使用二进制信号量

假设您有四个线程。创建初始值为
{1,0,0,0}
的四个信号量。为每个线程分配信号量,并让每个线程
在启动时向下
其信号量,然后
向上
下一个信号量(线程的模数)在链中。启动所有线程-第一个线程立即获取其信号量,执行其工作,其他线程阻塞其信号量。第一个线程完成工作,
up
s下一个信号量,从而唤醒下一个线程,然后循环到开头,等等

我认为你提到的实时课程安排与手头的问题无关

关于代码的一些注释:

  • 不受锁保护的变量在线程之间发出状态变化的信号(如这里的
    done
    )必须是
    volatile
    ,所以编译器不会在循环外对它们进行优化
  • 您可以使用thread函数参数向线程传递更复杂的信息,例如指向结构的指针
  • 您总是希望在循环中调用
    pthread\u cond\u wait
    ,循环条件检查您等待的内容。这是为了避免
  • 您总是希望在锁之外调用
    pthread\u cond\u signal
    ,或者作为解锁之前的最后一件事。这是为了避免在等待的线程中浪费唤醒/睡眠周期-它们醒来时,发现互斥锁仍然锁定,再次阻塞(睡眠)
  • 避免多个线程在同一个锁上竞争,这会导致问题
  • 始终检查
    pthread
    调用的返回值

希望这能有所帮助。

如果我正确理解了这个问题,那么您正在尝试生成一种管道,其中下一个线程在上一个线程停止的地方开始运行。在这种情况下,最干净的解决方案是使用二进制信号量

假设您有四个线程。创建初始值为
{1,0,0,0}
的四个信号量。为每个线程分配信号量,并让每个线程
在启动时向下
其信号量,然后
向上
下一个信号量(线程的模数)在链中。启动所有线程-第一个线程立即获取其信号量,执行其工作,其他线程阻塞其信号量。第一个线程完成工作,
up
s下一个信号量,从而唤醒下一个线程,然后循环到开头,等等

我认为你提到的实时课程安排与手头的问题无关

关于代码的一些注释:

  • 不受锁保护的变量在线程之间发出状态变化的信号(如这里的
    done
    )必须是
    volatile
    ,所以编译器不会在循环外对它们进行优化
  • 您可以使用thread函数参数向线程传递更复杂的信息,例如指向结构的指针
  • 您总是希望在循环中调用
    pthread\u cond\u wait
    ,循环条件检查您等待的内容。这是为了避免
  • 您总是希望在锁之外调用
    pthread\u cond\u signal
    ,或者作为解锁之前的最后一件事。这是为了避免在等待的线程中浪费唤醒/睡眠周期-它们醒来时,发现互斥锁仍然锁定,再次阻塞(睡眠)
  • 避免多个线程在同一个锁上竞争,这会导致问题
  • 始终检查
    pthread
    调用的返回值


希望这能有所帮助。

Hmm,我仍然错过了你正在尝试做的事情。我正在尝试以不同的方式有效地调度线程。这有帮助吗?我想使用SCHED_FIFO或SCHED_RR,但我不确定如何使用。你的inc_count函数对于那些if块来说非常糟糕。最好为每个线程使用不同的函数。还有ur'done'变量未锁定。编译器可以自由地将其粘贴到寄存器中,而您的其他线程将永远不会看到它。这可能会发生。祝贺您,在100行代码中,您至少有两个非常难以调试的线程heisenbug。:)嗯,我仍然不知道你想做什么。我正在尝试以不同的方式有效地调度线程。这有帮助吗?我想使用SCHED_FIFO或SCHED_RR,但我不知道如何使用。你的inc_count函数对于那些if块来说非常糟糕。最好为每个线程使用不同的函数。另外,你的'done'变量是not锁定。编译器可以自由地将其粘贴到寄存器中,而您的其他线程将永远不会看到它。这可能会发生。恭喜,在100行代码中,您至少有两个非常难以调试的线程Heisenbug。:)好的..那么我就必须为RR创建一个算法,对吗?好的..那么我就必须为RR创建一个算法,对吗?是的,其中一些是有意义的。我确实认为你使用信号量是正确的。我给信号量加1,-1推荐volatile做任何事情。所以这是一个清洗。@Zan:
volatile
在实践中是完美的发出“单向”/“边缘状态”信号的罚款
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
 #define NUM_THREADS  4
 #define TCOUNT 5
 #define COUNT_LIMIT 13

 int     done = 0;
 int    count = 0;
 int     thread_ids[4] = {0,1,2,3};
 int thread_runtime[4] = {0,5,4,1};
 pthread_mutex_t count_mutex;
 pthread_cond_t count_threshold_cv;

 void *inc_count(void *t)
 {
   int i;
   long my_id = (long)t;
   long run_time = thread_runtime[my_id];
   if (my_id==2 && done==0) {
     for(i=0; i<5 ; i++) {
       if (i==4) {
         done = 1;
       }
       pthread_mutex_lock(&count_mutex);
       count++;

       if (count == COUNT_LIMIT) {
         pthread_cond_signal(&count_threshold_cv);
         printf("inc_count(): thread %ld, count = %d  Threshold reached.\n",
           my_id, count);
       }
       printf("inc_count(): thread %ld, count = %d, unlocking mutex\n", my_id, count);
       pthread_mutex_unlock(&count_mutex);
     }
   }

   if (my_id==3 && done==1) {
     for(i=0; i< 4 ; i++) {
       if (i==3) {
         done = 2;
       }
       pthread_mutex_lock(&count_mutex);
       count++;

       if (count == COUNT_LIMIT) {
         pthread_cond_signal(&count_threshold_cv);
         printf("inc_count(): thread %ld, count = %d  Threshold reached.\n",
           my_id, count);
       }
       printf("inc_count(): thread %ld, count = %d, unlocking mutex\n", my_id, count);
       pthread_mutex_unlock(&count_mutex);
     }
   }

   if (my_id==4 && done==2) {
     for(i=0; i<8; i++) {
       pthread_mutex_lock(&count_mutex);
       count++;
       if (count == COUNT_LIMIT) {
         pthread_cond_signal(&count_threshold_cv);
         printf("inc_count(): thread %ld, count = %d  Threshold reached.\n",
           my_id, count);
       }
       printf("inc_count(): thread %ld, count = %d, unlocking mutex\n", my_id, count);
       pthread_mutex_unlock(&count_mutex);
     }
   }
   pthread_exit(NULL);
 }

 void *watch_count(void *t)
 {
   long my_id = (long)t;

   printf("Starting watch_count(): thread %ld\n", my_id);
   pthread_mutex_lock(&count_mutex);
   if (count<COUNT_LIMIT) {
     pthread_cond_wait(&count_threshold_cv, &count_mutex);
     printf("watch_count(): thread %ld Condition signal received.\n", my_id);
     count += 125;
     printf("watch_count(): thread %ld count now = %d.\n", my_id, count);
   }
   pthread_mutex_unlock(&count_mutex);
   pthread_exit(NULL);
 }

 int main (int argc, char *argv[])
 {
   int i, rc;
   long t1=1, t2=2, t3=3, t4=4;
   pthread_t threads[4];
   pthread_attr_t attr;

   pthread_mutex_init(&count_mutex, NULL);
   pthread_cond_init (&count_threshold_cv, NULL);
   pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
   pthread_create(&threads[0], &attr, watch_count, (void *)t1);
   pthread_create(&threads[1], &attr, inc_count, (void *)t2);
   pthread_create(&threads[2], &attr, inc_count, (void *)t3);
   pthread_create(&threads[3], &attr, inc_count, (void *)t4);

   for (i=0; i<NUM_THREADS; i++) {
     pthread_join(threads[i], NULL);
   }
   printf ("Main(): Waited on %d  threads. Done.\n", NUM_THREADS);

   pthread_attr_destroy(&attr);
   pthread_mutex_destroy(&count_mutex);
   pthread_cond_destroy(&count_threshold_cv);
   pthread_exit(NULL);
 }