同时启动所有主题

时间:2018-02-12 18:29:17

标签: c multithreading pthreads

我无法理解条件变量,例如pthread_mutex_lock / unlockpthread_cond_wait / signal

我正在尝试创建九个threads,并让它们同时运行以找出哪个效率最高。

    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;
}

...

所以当main函数启动时,我lock使用互斥锁来确保线程在我用pthread_lock(&amp; mutex)和pthread_cond_wait(&amp; cond,&amp; mutex)告诉它们之前没有启动

然后我用各种调度策略创建所有九个线程。在完成之后,我尝试使用pthread_mutex_unlock(&amp; mutex)和pthread_cond_signal(&amp; cond)

告诉线程全部同时启动

但是当我运行它时,它永远不会解锁线程。主函数的“running ...”打印语句消失,但线程永远不会启动。 (threadrunner有一个功能,他们都打印出大量不同的数字,所以我可以看看他们是否启动)。我对pthread mutex和pthread cond做错了什么?

3 个答案:

答案 0 :(得分:1)

来自pthread_cond_wait()手册页:

  

pthread_cond_wait()函数以原子方式阻塞当前线程   等待 cond 指定的条件变量,然后释放   由互斥锁指定的互斥锁。

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

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

......正如你的评论建议的那样,它将开始等待,直到有人发出条件变量的信号。

但是还没有其他线程产生,所以没有人在那里发出条件变量的信号,因此你的主线程在该调用中无限期地阻塞。

答案 1 :(得分:0)

我认为你想要做的就是这样。我用 pthread_cond_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

答案 2 :(得分:0)

对于临时基准测试而言,接受的答案“足够好”。但是,它使用了几个有问题的做法:没有谓词的条件变量,以及 sleep()作为ersatz同步。

使用pthreads barrier对象会更好,也很容易。

#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);

  ...
}