线程的组织方式:流水线结构

来源:互联网 发布:mac 强制退出程序死机 编辑:程序博客网 时间:2024/04/30 15:11

流水线结构

#include <pthread.h>#include "errors.h"typedef struct stage_tag {  pthread_mutex_t mutex; // 保持本阶段互斥的互斥锁  pthread_cond_t avail; // 是否空闲  pthread_cond_t ready; // 是否有数据  int data_ready; // 有数据标记  long data;  pthread_t thread; // 相应的线程  struct stage_tag *next;} stage_t;typedef struct pipe_tag {  pthread_mutex_t mutex;  stage_t *head, *tail;  int stages;  int active;} pipe_t;int pipe_send( stage_t *stage, long data ){  int status;    status = pthread_mutex_lock( &stage -> mutex );  if( status != 0 )    return status;  while( stage -> data_ready ) { // 如果有数据,则下面必须等待知道收到ready信号    status = pthread_cond_wait( &stage -> ready, &stage -> mutex );    if( status != 0 ) {      pthread_mutex_unlock( &stage -> mutex );      return status;    }  }  // 空闲则可以继续执行,传递data,置就绪位  stage -> data = data;  stage -> data_ready = 1;  // 此时有了data,就可以发送avail信号了  status = pthread_cond_signal( &stage -> avail );  if( status != 0 ) {    pthread_mutex_unlock( &stage -> mutex );    return status;  }  status = pthread_mutex_unlock( &stage -> mutex );  return status;}/*流水线线程*/void *pipe_stage( void *arg ){  stage_t *stage = ( stage_t * )arg;  stage_t *next_stage = stage -> next; // 下一个线程stage_t结构  int status;  status = pthread_mutex_lock( &stage -> mutex );  if( status != 0 )    err_abort( status, "lock pipe stage" );  while( 1 ) {    while( stage -> data_ready != 1 ) {      // 一开始data_ready是0,所以到这里一定会等待avail       // 如果数据已经就绪,则跳过这个while      status = pthread_cond_wait( &stage -> avail, &stage -> mutex );      if( status != 0 )err_abort( status, "wait for previous stage" );    }    pipe_send( next_stage, stage -> data + 1 ); // 向下一个stage发送数据    stage -> data_ready = 0; //之后这一个stage空闲,下面发送ready信号,继续处理数据    status = pthread_cond_signal( &stage -> ready );    if( status != 0 )      err_abort( status, "wake next stage" );  }}int pipe_create( pipe_t *pipe, int stages ){  int pipe_index;  stage_t **link = &pipe -> head, *new_stage, *stage;  int status;  status = pthread_mutex_init( &pipe -> mutex, NULL );  if( status != 0 )    err_abort( status, "init pipe mutex" );  pipe -> stages = stages;  pipe -> active = 0;  for( pipe_index = 0; pipe_index <= stages; ++ pipe_index ) {    new_stage = ( stage_t * )malloc( sizeof( stage_t ) );    if( new_stage == NULL )      errno_abort( "Allocate stage" );    status = pthread_mutex_init( &new_stage -> mutex, NULL );    if( status != 0 )      err_abort( status, "init stage mutex" );    status = pthread_cond_init( &new_stage -> avail, NULL );    if( status != 0 )      err_abort( status, "init avail condition" );    status = pthread_cond_init( &new_stage -> ready, NULL );    if( status != 0 )      err_abort( status, "init ready condition" );    new_stage -> data_ready = 0;    *link = new_stage;    link = &new_stage -> next;  }  *link= (stage_t * )NULL;  pipe -> tail = new_stage;  for( stage = pipe -> head;       stage -> next != NULL;       stage = stage -> next ) {    status = pthread_create( &stage -> thread, NULL, pipe_stage, ( void * )stage );    if( status != 0 )      err_abort( status, "Create pipe stage" );  }  return 0;  }int pipe_start( pipe_t *pipe, long value ) {  int status;    status = pthread_mutex_lock( &pipe -> mutex );  if( status != 0 )    err_abort( status, "lock pipe mutex" );  pipe -> active ++; // 目前活动的阶段数  status = pthread_mutex_unlock( &pipe -> mutex );  if( status != 0 )    err_abort( status, "Unlock pipe mutex" );  pipe_send( pipe -> head, value ); // 从第一个stage激活流水线  return 0;}int pipe_result( pipe_t *pipe, long *result ){  stage_t *tail = pipe -> tail;  long value;  int empty = 0;  int status;  status = pthread_mutex_lock( &pipe -> mutex );  if( status != 0 )    err_abort( status, "lock pipe mutex" );  if( pipe -> active <= 0 )    empty = 1;  else    pipe -> active --;  status = pthread_mutex_unlock( &pipe -> mutex );  if( status != 0 )    err_abort( status, "unlock pipe mutex" );  if( empty )    return 0;    pthread_mutex_lock( &tail -> mutex );  while( !tail -> data_ready )    pthread_cond_wait( &tail -> avail, &tail -> mutex );  *result = tail -> data;  tail -> data_ready = 0;  pthread_cond_signal( &tail -> ready );  pthread_mutex_unlock( &tail -> mutex );  return 1;}int main( int argc, char *argv[] ){  pipe_t my_pipe;  long value, result;  int status;  char line[ 128 ];  pipe_create( &my_pipe, 10 );  printf( "Enter integer values, or \"=\" for next result\n" );  while( 1 ) {    printf( "Data> " );    if( fgets( line, sizeof( line ), stdin ) == NULL )      exit( 0 );    if( strlen( line ) <= 1 )      continue;    if( strlen( line ) <= 2 && line[ 0 ] == '=' ) {      if( pipe_result( &my_pipe, &result ) )printf( "Result is %ld\n", result );      elseprintf( "Pipe is empty\n" );    }    else {      if( sscanf( line, "%ld", &value ) < 1 )fprintf( stderr, "Enter an integer value\n" );      elsepipe_start( &my_pipe, value );    }  }}


原创粉丝点击