gpt4 book ai didi

c - 线程调度C

转载 作者:太空宇宙 更新时间:2023-11-04 07:42:20 24 4
gpt4 key购买 nike

 #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 的内容。我想我不知道如何将它们实现到这段代码中,或者是否可以实现

最佳答案

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

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

我认为你提到的实时调度类与手头的问题无关。

关于您的代码的一些注释:

  • 不受信号状态在线程之间变化的锁保护的变量(如此处的done)必须是volatile,因此编译器不会优化他们脱离了循环。
  • 您可以使用线程函数参数将更复杂的信息传递给线程,例如指向结构的指针。
  • 您总是希望在循环中调用 pthread_cond_wait ,循环条件会检查您等待的事情。这是为了避免 spurious wakeups .
  • 您总是希望在锁外调用 pthread_cond_signal,或者在解锁之前的最后一件事。这是为了避免在等待线程中浪费唤醒/ sleep 周期 - 它们醒来后发现互斥体仍然锁定,再次阻塞( sleep )。
  • 避免许多线程争用同一个锁,这会导致 thundering herd问题。
  • 总是检查 pthread 调用的返回值。

希望这对您有所帮助。

关于c - 线程调度C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2582342/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com