#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);
}
所以这段代码创建了4个线程。线程1跟踪计数值,而另一个3增加计数值。运行时间是线程递增计数值的次数。我有一个完成值,允许第一个线程首先递增计数值,直到它的运行时间结束..所以它就像先到先服务。
我的问题是:有更好的方法来实现吗?我读过有关SCHED_FIFO或SCHED_RR的内容。我想我不知道如何在这段代码中实现它们,或者它是否可以
答案 0 :(得分:2)
如果我正确地理解了这个问题,那么你正试图产生一种管道,其中下一个线程会在前一个线程停止的地方找到。在这种情况下,最干净的解决方案是使用二进制信号量。
假设您有四个主题。创建四个信号量,初始值为{1, 0, 0, 0}
。为每个线程分配信号量,并在开始时让每个线程down
为其信号量,并在链中为up
提供下一个信号量(模数线程数)。启动所有线程 - 第一个线程立即获取其信号量,执行其工作,其他线程阻塞其信号量。第一个线程完成工作,up
是下一个信号量,因此唤醒下一个线程,然后循环到开头等等。
我认为你提到的实时调度类与手头的问题无关。
关于您的代码的一些注意事项:
done
))必须为 volatile
,因此编译器不会将它们优化出循环。 pthread_cond_wait
,其中循环条件会检查您等待的内容。这是为了避免spurious wakeups。pthread_cond_signal
,或者在解锁前最后一次调用pthread
。这是为了避免等待线程中浪费的唤醒/睡眠周期 - 它们唤醒,发现互斥锁仍然锁定,再次阻塞(睡眠)。希望这有帮助。
答案 1 :(得分:1)
SCHED_FIFO和SCHED_RR是实时调度类。它们不适用于普通代码。您应该可以使用pthread互斥锁执行大部分操作。