C++(26)-多线程-POSIX(4)-一个主线程+多个工作线程

一般情况下,我们会有一个主线程和多个工作线程。
如下图所示:

把众多的子线程分成工作队列非工作队列进行管理。
1.工作节点,工作队列;非工作节点,非工作队列结构体定义。
2.main函数运行流程。
3.调用过程中的5个函数:
    线程运行函数threadfunc(),
    添加线程函数 join_threads(),
   创建线程函数 create_threads(),
   初始化结构函数initialize_structs(),
   销毁结构化函数cleanup_structs()。


1.工作节点,工作队列;非工作节点,非工作队列结构体定义。

//工作线程队列 
struct work_queue {
  data_control control;
  queue work;
} wq;
//工作线程node
typedef struct work_node {
  struct node *next;
  int jobnum;
} wnode;
//未工作队列
struct cleanup_queue {
  data_control control;
  queue cleanup;
} cq;
//非工作的线程node
typedef struct cleanup_node {
  struct node *next;
  int threadnum;
  pthread_t tid;
} cnode;

2.main函数运行流程

int main(void) {
    //1.初始化
  int x;
  wnode *mywork;
  initialize_structs();
  
  //2.创建
  if (create_threads()) {
    printf("Error starting threads... cleaning up.\n");
    join_threads();
    dabort();
  }
  //3.工作队列添加互斥变量
  pthread_mutex_lock(&wq.control.mutex);
  for (x=0; x<16000; x++) 
  {
    mywork=malloc(sizeof(wnode));
    if (!mywork) 
    {
      printf("ouch! can't malloc!\n");
      break;
    }
    mywork->jobnum=x;
    queue_put(&wq.work,(node *) mywork);
  }
  pthread_mutex_unlock(&wq.control.mutex);
    
  //4.工作线程广播
  pthread_cond_broadcast(&wq.control.cond);
  printf("sleeping...\n");
  sleep(2);
   //5.监管工作线程
  printf("deactivating work queue...\n");
  control_deactivate(&wq.control);
    
  //6.添加线程
  join_threads();
  
  //7.清理
  cleanup_structs();
}
 

3.调用过程中的5个函数:
 

//1.线程函数 处理工作线程+清理线程
void *threadfunc(void *myarg) {
  wnode *mywork;   //工作的线程node
  cnode *mynode;   //非工作的线程node
  mynode=(cnode *) myarg;
  //1.1工作队列加互斥
  pthread_mutex_lock(&wq.control.mutex);
  //工作队列是激活状态
  while (wq.control.active) 
  {
    while (wq.work.head==NULL && wq.control.active) //工作队里中无线程+是激活状态
    {
      pthread_cond_wait(&wq.control.cond, &wq.control.mutex);//等待线程
    }
    if (!wq.control.active) 
      break;
    mywork=(wnode *) queue_get(&wq.work);    //得到工作线程
    pthread_mutex_unlock(&wq.control.mutex);//去掉互斥量
    printf("Thread number %d processing job %d\n",mynode->threadnum,mywork->jobnum);
    free(mywork);
    pthread_mutex_lock(&wq.control.mutex);
  }    
  // 1.2工作队列解锁
  pthread_mutex_unlock(&wq.control.mutex);
    
  //2.1非工作队列加互斥
  pthread_mutex_lock(&cq.control.mutex);
  queue_put(&cq.cleanup,(node *) mynode);
  //2.2非工作队列加互斥
  pthread_mutex_unlock(&cq.control.mutex);
  //等待条件
  pthread_cond_signal(&cq.control.cond);
  printf("thread %d shutting down...\n",mynode->threadnum);
  return NULL;
  
}

#define NUM_WORKERS 4
int numthreads;
//2.添加线程 把线程添加到线程链表中
void join_threads(void) {
  cnode *curnode;    //非工作线程节点
  printf("joining threads...\n");
  while (numthreads) 
  {
    //添加互斥量
    pthread_mutex_lock(&cq.control.mutex);
     while (cq.cleanup.head==NULL) 
     {
      pthread_cond_wait(&cq.control.cond,&cq.control.mutex);
    }
    //添加到队列中
     curnode = (cnode *) queue_get(&cq.cleanup);
      pthread_mutex_unlock(&cq.control.mutex);
    //解除互斥量
      pthread_join(curnode->tid,NULL);
      printf("joined with thread %d\n",curnode->threadnum);
      free(curnode);
      numthreads--;
  }
}
//3.创建线程 创建了一个线程Id,并把Id放入工作队列中
int create_threads(void) 
{
  int x;
  cnode *curnode;    //非工作线程节点
  for (x=0; x<NUM_WORKERS; x++) 
  {
    curnode=malloc(sizeof(cnode));
    if (!curnode)
      return 1;
    curnode->threadnum=x;
    if (pthread_create(&curnode->tid, NULL, threadfunc, (void *) curnode))
      return 1;
    printf("created thread %d\n",x);
    numthreads++;
  }
  return 0;
}
//4.初始化 工作队列+非工作队列
void initialize_structs(void) {
  numthreads=0;
  if (control_init(&wq.control))
    dabort();
  queue_init(&wq.work);
  if (control_init(&cq.control)) {
    control_destroy(&wq.control);
    dabort();
  }
  queue_init(&wq.work);
  control_activate(&wq.control);
}

//5.销毁结构函数
void cleanup_structs(void) {
  control_destroy(&cq.control);
  control_destroy(&wq.control);
}

 

posted @ 2020-11-27 12:56  jasmineTang  阅读(101)  评论(0)    收藏  举报