当前位置: 首页 > 知识库问答 >
问题:

同时启动所有线程

寿子轩
2023-03-14

我在理解诸如pthread\u mutex\u lock/unlockpthread\u cond\u wait/signal

我试图创建九个线程,并让它们同时运行,以找出哪个是最有效的。

    int threadNumber = 0;
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

    #define NUM_THREADS    9

    //used to store the information of each thread
    typedef struct{
        pthread_t  threadID;
        int policy;
        struct sched_param param;
        long startTime;
        long taskStartTime;
        long endTime1;
        long endTime2;
        long endTime3;
        long runTime;
        char startDate[30];
        char endDate[30];
    }ThreadInfo;

ThreadInfo myThreadInfo[NUM_THREADS];



//main function
int main(void){

   printf("running...\n");

   pthread_mutex_lock(&mutex); //lock the mutex//////
   pthread_cond_wait(&cond, &mutex); //start waiting//////


   int fifoPri = 60;
   int rrPri = 30;

   //create the 9 threads and assign their scheduling policies
   for(int i=0; i<NUM_THREADS; i++){

      if(i%3 == SCHED_OTHER){
            myThreadInfo[i].policy = SCHED_OTHER;
            myThreadInfo[i].param.sched_priority = 0;

      }
      else if (i%3 == SCHED_RR){ 
            myThreadInfo[i].policy = SCHED_RR;
            myThreadInfo[i].param.sched_priority = rrPri++; 
      }

      else{
            myThreadInfo[i].policy = SCHED_FIFO; 
            myThreadInfo[i].param.sched_priority = fifoPri++; 

      }

      pthread_create( &myThreadInfo[i].threadID, NULL, ThreadRunner, &myThreadInfo[i]);

   }

   printf("\n\n");

   pthread_mutex_unlock(&mutex) //unlock the mutex/////////
   pthread_cond_signal(&cond); //signal the threads to start////////


   //join each thread
   for(int g = 0; g < NUM_THREADS; g++){
      pthread_join(myThreadInfo[g].threadID, NULL);
   }


   //print out the stats for each thread and perform an analysis of the data
   DisplayThreadSchdStats();


   return 0;
}

...

因此,当主函数启动时,我会锁定互斥锁,以确保线程不会启动,然后再告诉它们使用pthread_lock(

然后,我使用各种调度策略创建所有九个线程。完成后,我尝试使用pthread\u mutex\u unlock告诉所有线程同时启动(

但当我运行这个时,它永远不会解锁线程。主功能的“运行…”print语句将关闭,但线程从未启动。(threadrunner有一个功能,它们都打印出大量不同的数字,这样我就可以看到它们是否启动了)。pthread互斥体和pthread cond有什么错?

共有3个答案

严开宇
2023-03-14

我想你想做的就是这样。我使用pthread\u cond\u broadcast一次唤醒所有线程

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>


pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

struct data_t {
    int id;
    int sleep;
};

void* thread(void *arg)
{
    struct data_t *data = arg;


    pthread_mutex_lock(&mutex);
    printf("Thread %d: waiting for release\n", data->id);

    pthread_cond_wait(&cond, &mutex);
    pthread_mutex_unlock(&mutex); // unlocking for all other threads

    struct timeval tv;
    gettimeofday(&tv, NULL);    

    printf("Thread %d: doing some work for %d secs, started: %ld...\n", data->id, data->sleep, tv.tv_sec);
    sleep(data->sleep);
    gettimeofday(&tv, NULL);    
    printf("Thread %d: Bye, end at %ld\n", data->id, tv.tv_sec);
}

int main(void)
{

    struct data_t data[9];
    pthread_t ths[9];

    srand(time(NULL));

    for(int i = 0; i < 9; ++i)
    {
        data[i].id = i + 1;
        data[i].sleep = 1 + rand() % 6;

        pthread_create(ths + i, NULL, thread, data + i);
    }

    // give time for all threads to lock
    sleep(1);

    printf("Master: Now releasing the condition\n");

    pthread_cond_broadcast(&cond);

    for(int i = 0; i < 9; ++i)
        pthread_join(*(ths + i), NULL);

    return 0;
}

输出是

Thread 2: waiting for release
Thread 6: waiting for release
Thread 4: waiting for release
Thread 1: waiting for release
Thread 3: waiting for release
Thread 8: waiting for release
Thread 9: waiting for release
Thread 7: waiting for release
Thread 5: waiting for release
Master: Now releasing the condition
Thread 5: doing some work for 6 secs, started: 1518463908...
Thread 2: doing some work for 4 secs, started: 1518463908...
Thread 8: doing some work for 1 secs, started: 1518463908...
Thread 4: doing some work for 4 secs, started: 1518463908...
Thread 6: doing some work for 1 secs, started: 1518463908...
Thread 9: doing some work for 5 secs, started: 1518463908...
Thread 3: doing some work for 2 secs, started: 1518463908...
Thread 1: doing some work for 3 secs, started: 1518463908...
Thread 7: doing some work for 2 secs, started: 1518463908...
Thread 8: Bye, end at 1518463909
Thread 6: Bye, end at 1518463909
Thread 3: Bye, end at 1518463910
Thread 7: Bye, end at 1518463910
Thread 1: Bye, end at 1518463911
Thread 2: Bye, end at 1518463912
Thread 4: Bye, end at 1518463912
Thread 9: Bye, end at 1518463913
Thread 5: Bye, end at 1518463914
闾丘书
2023-03-14

pthread\u cond\u wait()手册页:

函数pthread_cond_wait()以原子方式阻止当前线程在cond指定的条件变量上等待,并释放mutex指定的互斥。

...所以当你的main()函数到达这一行时:

pthread_cond_wait(&cond, &mutex); //start waiting//////

... 如条件所示,直到有人发出您的注释信号为止。

但是还没有生成其他线程,因此没有人向条件变量发送信号,因此主线程在该调用中无限期地阻塞。

梁丘洲
2023-03-14

就临时基准而言,公认的答案是“足够好”。然而,它使用了几个有问题的实践:不带谓词的条件变量和替代同步的睡眠()。

使用pthreadsbarrier对象更好、更简单。

#define NUM_THREADS ...

static pthread_barrier_t bar;

static void*
thrfunc(void *arg) {
  // set scheduling policy

  pthread_barrier_wait(&bar); // wait till all peers have also done so

  ...
}

int
main(void) {
  pthread_barrier_init(&bar, NULL, NUM_THREADS); // FIXME: error check

  for (int i = 0; i < NUM_THREADS; i++) {
    // spawn threads with various scheduling policy instructions
  }

  // join and tabulate results

  pthread_barrier_destroy(&bar);

  ...
}

但是如果你的平台不支持壁垒怎么办?在这种情况下,您可以实现“一次性障碍”,等待N方到达。

您的主线程将init_quorum(NUM_THREADS),而辅助角色将await_quorum(...),只有当所有辅助角色都准备好时才前进。

struct quorum {
  pthread_cond_t  cond;
  pthread_mutex_t mut;
  size_t          count;  // How many are needed?
};

void
await_quorum(struct quorum *q) {  // FIXME: error checking
  pthread_mutex_lock(&q->mut);

  if (q->count > 0) {
    q->count--;

    if (q->count == 0) {
      // I'm the last needed; we have quorum
      pthread_cond_broadcast(&q->cond);
    } else {
      // Wait for sufficient threads to arrive
      while (q->count > 0)
        pthread_cond_wait(&q->cond, &q->mut);
    }
  } // else quorum already achieved; I'm late!

  pthread_mutex_unlock(&q->mut);
}
 类似资料:
  • 我一直在尝试写一些java应用程序。这个应用程序想要运行的是处理一个文本文件。 但是,输入文本文件很大(超过200MB),我尝试将200MB拆分为四个拆分文件(每个50MB) 所以,每一个都只需要0.5秒,但是用这种线性运行,每一个也需要2秒。(worker1+0.5s,worker2+0.5s,worker3+0.5s,worker4)如果我可以同时运行4个线程,我预计这个应用程序只需要0.5秒

  • 问题内容: 程应在同一瞬间开始。我了解,如果你这样做,则下次执行之前需要花费几毫秒的时间。 可能还是不可能?线程应该在同一瞬间开始。我知道,如果你执行,则下次执行thread2.start()需要几毫秒。 这是可能的还是不可能的? 问题答案: 要完全同时(至少尽可能好)启动线程,可以使用CyclicBarrier: 这不必是,你也可以使用 这仍然无法确保它们已正确启动 在其他平台上,确切地说启动线

  • 我发现当从非主线程启动时,ServerSocket在一定程度上变得不负责任。为什么?当我在主线程中启动ServerSocket时,一切正常。 主要开始类: 启动ServerSocket并接受连接的线程类: 通讯线程: 客户端测试应用程序 启动10个连接的主启动类: 连接Thread: 控制台输出: 客户端测试结果显示并非所有连接都被接受: 服务器控制台仅显示4个接受的连接:

  • 当我的应用程序启动时,将创建一个executor服务(在java.util.concurrent中使用Executors.NewFixedThreadPool(maxThreadNum))对象。当请求到来时,executor服务将创建线程来处理它们。 当应用程序启动时,它将在executorService池中创建200个线程。 只是想知道当应用程序启动时,这是一种正确的创建线程的方法吗?还是有更好

  • 我正在做一个遗留项目,它使用了Java 8、Spring、HikariCP和MySQL。微服务的方法由Kafka主题触发,并开始报告操作。几乎所有的触发方法都有这样的用法,其中一些在它们的块中有相同的用法。 原因:java.sql.SQLTransientConnection异常:HikariPool-2 - 连接不可用,请求在 30000 毫秒后超时。 当我检查数据库并看到 max_connec

  • 我想在我的虚拟服务器上启动一个野蝇。每次我运行./wilfly/bin/standalone.sh我在无融资创业时都会收到以下错误: 让我得到以下信息: 如您所见,虚拟内存是无限的,最大用户进程非常大。 在启动本文中描述的jvm时,我还使用-Xss256kb增加/减少了堆栈大小,但没有任何成功。 同样在standalone.xml中为每个子系统增加50也不起作用(在本文中描述)。 您还有其他想法如