通过调用pthread_cond_wait和pthread_cond_signal会在C / C执行多个线程在一个循环方式++ [英] Executing multiple threads in a round robin fashion using pthread_cond_wait and pthread_cond_signal in c/c++

查看:169
本文介绍了通过调用pthread_cond_wait和pthread_cond_signal会在C / C执行多个线程在一个循环方式++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了10个线程,并希望在一个循环的方式执行3次。最初,所有
线程正在等待。主线程发送信号给线程0,在接收信号的线程0醒了,
然后执行一些任务,然后将信号发送到线程1和重复类似thread1-> thread2-> thread3
....-> thread9。那么线程9->线程0。

我想实现这个

主题我,做一些任务,然后将信号发送到线程(我+ 1),然后拧我去睡觉。螺纹(I + 1)将在t秒后醒来(指线程i + 1的唤醒时间 - 线程我睡眠时间= T秒)螺纹(I + 1)会做一些任务,将信号发送到线程(我+ 2)和去睡眠,这将重复数(3)倍。

虽然我能够从线程0->线程发送信号1 - > ....螺纹9(循环只执行一次),我无法发送信号线9 - >线程0 这就是为什么我不能够重复这个循环 3次。

我在哪里犯错?

任何帮助将是非常美联社preciated。
我使用的G ++ 4.6.3下的Linux内核2.6.32。

这是我期望的输出

 创建5个线程
    线程创建= 0
    线程创建= 1
    线程创建= 2
    线程创建= 3
    线程创建= 4
    螺纹4受阻
    螺纹盖帽3
    线程2阻塞
    线程1被阻止
    线程0受阻
    唤醒所有等待的线程...
    线程0畅通
    线程1畅通
    线程2畅通
    线程3畅通
    主题4畅通    螺纹4阻塞//相同序列的repeataion
    螺纹盖帽3
    线程2阻塞
    线程1被阻止
    线程0受阻
    线程0畅通
    线程1畅通
    线程2畅通
    线程3畅通
    主题4畅通
    等待线程和清理
    主体完工

下面是我的实际输出

 创建5个线程
线程创建= 0
线程创建= 1
线程创建= 2
线程创建= 3
线程创建= 4
螺纹4受阻
螺纹盖帽3
线程2阻塞
线程1被阻止
线程0受阻
唤醒所有等待的线程...
线程0畅通
线程1畅通
线程2畅通
线程3畅通
主题4畅通
等待线程和清理
主体完工

下面是我的code

 的#include< pthreads.h中>
#包括LT&;&iostream的GT;
#包括LT&;&stdio.h中GT;
/ *为了安全条件变量使用,必须使用一个布尔值predicate和* /
/ *与条件的互斥。 * /
INT conditionMet = 0;
pthread_cond_t的COND [5];pthread_mutex_t互斥= PTHREAD_MUTEX_INITIALIZER;#定义来确定nthreads 5无效*的ThreadFunc(无效* PARM)
{  INT I;
  长期添加my_id =(长)PARM;
  INT RC;//最初,所有的线程将等待
RC的pthread_mutex_lock =(安培;互斥);
的printf(线程%d个阻塞\\ n,添加my_id);
RC =调用pthread_cond_wait(安培; COND [添加my_id]&安培;互斥);
的printf(线程%d个畅通\\ n,添加my_id);
RC =调用pthread_mutex_unlock(安培;互斥);诠释计数= 0;而(计数++ 3;)//此行是没有意义的,因为没有预期repeatation。
{  RC的pthread_mutex_lock =(安培;互斥);  而(!conditionMet){
    的printf(线程%d个阻塞\\ n,添加my_id);
    RC =调用pthread_cond_wait(安培; COND [添加my_id]&安培;互斥);
    的printf(线程%d个畅通\\ n,添加my_id);
  }  RC =调用pthread_mutex_unlock(安培;互斥);  //发送信号给下一个线程I + 1
 RC的pthread_mutex_lock =(安培;互斥);
    RC =调用pthread_cond_signal(安培; COND [(添加my_id + 1)%来确定nthreads]);
    RC =调用pthread_mutex_unlock(安培;互斥);   }
      返回NULL;
   }    INT主(INT ARGC,字符** argv的)
    {
  INT RC = 0;
  INT I;
  的pthread_t主题ID [确定nthreads]    对于(RC = 0;&RC LT;确定nthreads; RC ++)
    COND [RC] = PTHREAD_COND_INITIALIZER;  的printf(请输入测试用例 - %S \\ N的argv [0]);  的printf(创建%d个线程的\\ n,确定nthreads);
  对于(i = 0; I<确定nthreads ++我){
    RC = pthread_create的(安培;主题ID [Ⅰ],NULL的ThreadFunc,(无效*)ⅰ);
    的printf(线程创建=%d个\\ N,I);
  }  睡眠(5); / *睡不序列化线程一个非常可靠的方法* /
  RC的pthread_mutex_lock =(安培;互斥);  / *条件已发生。设置该标志并唤醒等待的线程* /
  conditionMet = 1;
  的printf(醒醒所有等待的线程... \\ n);
  RC =调用pthread_cond_signal(放大器; COND [0]);
  RC =调用pthread_mutex_unlock(安培;互斥);  的printf(等待线程和清理\\ n);
  对于(i = 0; I<确定nthreads ++我){
    RC =在pthread_join(主题ID [I],NULL);
  }
  pthread_cond_destroy(安培; COND [0]);
  pthread_mutex_destroy(安培;互斥);  的printf(主完成\\ n);
  返回0;
}


解决方案

后pthread_wait 我自己解决我的问题。

中的所有线程循环赛序列运行一次,然后该程序终止/完整的执行为否线程都在等待下一回合后,全部完成。

所以要运行相同的多个序列(3)次,等变量需要正确地修改,以便每个线程将等待下一回合,直到3执行。

下面是修改后的程序:

 无效*的ThreadFunc(无效* PARM)
{  INT I;
  长期添加my_id =(长)PARM;
  INT RC;   / *
 删除这部分,否则无输出,AGAIN绞死单个序列。
 它不会进入里面循环while(计数++ 3;)    //最初,所有的线程将等待
    RC的pthread_mutex_lock =(安培;互斥);
    的printf(线程%d个阻塞\\ n,添加my_id);
    RC =调用pthread_cond_wait(安培; COND [添加my_id]&安培;互斥);
    的printf(线程%d个畅通\\ n,添加my_id);
    RC =调用pthread_mutex_unlock(安培;互斥);
    * /
诠释计数= 0;而(计数++ 3;)
{  RC的pthread_mutex_lock =(安培;互斥);
  而(conditionMet!=添加my_id)
   {
    的printf(线程%d个阻塞\\ n,添加my_id);
    RC =调用pthread_cond_wait(安培; COND [添加my_id]&安培;互斥);
    的printf(线程%d个畅通\\ n,添加my_id);
   }    RC =调用pthread_mutex_unlock(安培;互斥);
    RC的pthread_mutex_lock =(安培;互斥);
    conditionMet =(添加my_id + 1)%来确定nthreads; //这是重要的,以等待下一次
    RC =调用pthread_cond_signal(安培; COND [(添加my_id + 1)%来确定nthreads]);
    RC =调用pthread_mutex_unlock(安培;互斥);
}
  返回NULL;
}

I have created 10 threads and want to execute in a round robin fashion for 3 times. Initially all threads are waiting. Main threads sends signal to thread 0, on receiving signal thread 0 woke up and then perform some task and then send signal to thread 1 and this repeats like thread1-> thread2->thread3 ....->thread9. then thread 9-> thread 0.

I am trying to implement this

thread i, does some task, then send signal to thread (i+1) and then thread i goes for sleep. thread (i+1) will wake up after t sec (means thread i+1 wakeup time - thread i sleep time = t sec ), thread (i+1) will do some task, send signal to thread (i+2) and go for sleep and this will repeat for few(3) times.

Although I am able to send signal from thread 0-> thread 1 -> .... thread 9 (loop executed only once ), I am not able to send signal thread 9 -> thread 0 and that's why I am not able to repeat this loop for 3 times.

where I am making mistakes ?

Any help will be highly appreciated . I am using g++ 4.6.3 under linux kernel 2.6.32.

Here is my expected output

    Create 5 threads
    Thread created=0
    Thread created=1
    Thread created=2
    Thread created=3
    Thread created=4
    Thread 4 blocked
    Thread 3 blocked
    Thread 2 blocked
    Thread 1 blocked
    Thread 0 blocked
    Wake up all waiting threads...
    Thread 0 unblocked
    Thread 1 unblocked
    Thread 2 unblocked
    Thread 3 unblocked
    Thread 4 unblocked

    Thread 4 blocked // repeataion of same sequence
    Thread 3 blocked
    Thread 2 blocked
    Thread 1 blocked
    Thread 0 blocked
    Thread 0 unblocked
    Thread 1 unblocked
    Thread 2 unblocked
    Thread 3 unblocked
    Thread 4 unblocked


    Wait for threads and cleanup
    Main completed

Here is my actual output

Create 5 threads
Thread created=0
Thread created=1
Thread created=2
Thread created=3
Thread created=4
Thread 4 blocked
Thread 3 blocked
Thread 2 blocked
Thread 1 blocked
Thread 0 blocked
Wake up all waiting threads...
Thread 0 unblocked
Thread 1 unblocked
Thread 2 unblocked
Thread 3 unblocked
Thread 4 unblocked
Wait for threads and cleanup
Main completed

Here is my code

#include <pthread.h>
#include <iostream>
#include <stdio.h>


/* For safe condition variable usage, must use a boolean predicate and   */
/* a mutex with the condition.                                           */
int                 conditionMet = 0;
pthread_cond_t      cond[5];

pthread_mutex_t     mutex = PTHREAD_MUTEX_INITIALIZER;

#define NTHREADS    5

void *threadfunc(void *parm)
{

  int i;
  long my_id = (long)parm;
  int           rc;

// Initially all threads will wait 
rc = pthread_mutex_lock(&mutex);
printf("Thread %d blocked\n",my_id);
rc = pthread_cond_wait(&cond[my_id], &mutex);
printf("Thread %d unblocked\n", my_id);
rc = pthread_mutex_unlock(&mutex);

int count=0;

while(count++<3) // This line makes no sense, no repeatation as expected. 
{

  rc = pthread_mutex_lock(&mutex);

  while (!conditionMet) {
    printf("Thread %d blocked\n",my_id);
    rc = pthread_cond_wait(&cond[my_id], &mutex);
    printf("Thread %d unblocked\n", my_id);
  }

  rc = pthread_mutex_unlock(&mutex);

  // sending signal to next thread i+1
 rc = pthread_mutex_lock(&mutex);
    rc = pthread_cond_signal(&cond[(my_id+1)%NTHREADS]);
    rc = pthread_mutex_unlock(&mutex);

   }
      return NULL;
   }

    int main(int argc, char **argv)
    {
  int                   rc=0;
  int                   i;
  pthread_t             threadid[NTHREADS];

    for(rc=0;rc<NTHREADS;rc++)
    cond[rc]= PTHREAD_COND_INITIALIZER;

  printf("Enter Testcase - %s\n", argv[0]);

  printf("Create %d threads\n", NTHREADS);
  for(i=0; i<NTHREADS; ++i) {
    rc = pthread_create(&threadid[i], NULL, threadfunc, (void *)i);
    printf("Thread created=%d\n", i);
  }

  sleep(5);  /* Sleep is not a very robust way to serialize threads */
  rc = pthread_mutex_lock(&mutex);

  /* The condition has occured. Set the flag and wake up any waiting threads */
  conditionMet = 1;
  printf("Wake up all waiting threads...\n");
  rc = pthread_cond_signal(&cond[0]);    
  rc = pthread_mutex_unlock(&mutex);      

  printf("Wait for threads and cleanup\n");
  for (i=0; i<NTHREADS; ++i) {
    rc = pthread_join(threadid[i], NULL);        
  }
  pthread_cond_destroy(&cond[0]);
  pthread_mutex_destroy(&mutex);

  printf("Main completed\n");
  return 0;
}

解决方案

After referring to pthread_wait I myself solved my problem.

All the threads runs in a round robin sequence for once, then the program terminate/complete execution as NO threads are WAITING for next turn, all finished .

So to run the same sequence multiple (3) times, wait variable needs to modified correctly so that each thread will wait for next turn until 3 execution.

Here is modified program :

void *threadfunc(void *parm)
{

  int i;
  long my_id = (long)parm;
  int           rc;

   /*
 DELETE THIS PORTION, OTHERWISE NO OUTPUT, AGAIN HANGED BEFORE SINGLE SEQUENCE.
 IT WILL NOT ENTER INSIDE LOOP while(count++<3)

    // Initially all threads will wait 
    rc = pthread_mutex_lock(&mutex);
    printf("Thread %d blocked\n",my_id);
    rc = pthread_cond_wait(&cond[my_id], &mutex);
    printf("Thread %d unblocked\n", my_id);
    rc = pthread_mutex_unlock(&mutex);
    */


int count=0;

while(count++<3)
{

  rc = pthread_mutex_lock(&mutex);
  while ( conditionMet != my_id) 
   {
    printf("Thread %d blocked\n",my_id);
    rc = pthread_cond_wait(&cond[my_id], &mutex);
    printf("Thread %d unblocked\n", my_id);
   }

    rc = pthread_mutex_unlock(&mutex);     
    rc = pthread_mutex_lock(&mutex);
    conditionMet = (my_id+1)%NTHREADS ; // This is important to wait for next time
    rc = pthread_cond_signal(&cond[(my_id+1)%NTHREADS]);
    rc = pthread_mutex_unlock(&mutex);
}
  return NULL;
}

这篇关于通过调用pthread_cond_wait和pthread_cond_signal会在C / C执行多个线程在一个循环方式++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆