POSIX 学习笔记---工作流

POSIX 工作流 :

每个线程反复的在数据系列集上执行同一种操作,并把操作结果传递给下一步骤的其他线程。


workflow_digram

每个线程由 stage_t 描述:

一个互斥量 m_mutex

两个条件变量:

m_ready_cond:表示当前的线程准备好处理新数据

m_available_cond:表示通知下一步数据已经可用


整个流水线由 pipe_t 描述,构造了一个流水线的队列。

handle_message 和 send 方法是线程的核心用来处理当前的消息和向下一步处理发送数据。

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

typedef struct _stage_t
{
    pthread_t        m_tid;
    int              m_tIdx;
    pthread_mutex_t  m_mutex;
    pthread_cond_t   m_ready_cond;
    pthread_cond_t   m_available_cond;
    
    int              m_ready;
    int              m_act;
    char             m_data[80];
    struct _stage_t* m_next;
} stage_t;

typedef struct _pipe_t
{
    stage_t*        m_head;
    stage_t*        m_tail;
    int             m_stages;
    pthread_mutex_t m_mutex;
    int             m_active;
} pipe_t;

typedef struct _msg_struct
{
    int    m_msgID;
    int    m_value;
    char   m_buff[64];
} msg_t;

void send(stage_t* pStage, char *pData, int nAct)
{
    if ((NULL == pStage) || (NULL == pData))    
    {
        return;    
    }
    
    pthread_mutex_lock(&pStage->m_mutex);
    while(pStage->m_ready)
    {
        pthread_cond_wait(&pStage->m_ready_cond, &pStage->m_mutex);
    }
    
    pStage->m_ready = 1;
    pStage->m_act = nAct;
    
    memcpy(pStage->m_data, pData, sizeof(msg_t));
    pthread_cond_signal(&pStage->m_available_cond);
    pthread_mutex_unlock(&pStage->m_mutex);
}

void* handle_message(void* arg)
{
    stage_t* pStage = NULL;
    if (NULL == arg)
    {
        return;
    }
    
    pStage = (stage_t*) arg;
    msg_t* pMsg = (msg_t*)&pStage->m_data;
    
    pthread_mutex_lock(&pStage->m_mutex);
    while(1)
    {
        while(pStage->m_ready != 1)
        {
            pthread_cond_wait(&pStage->m_available_cond, &pStage->m_mutex);    
        }
        printf("tid=%d recv msg: %s\n",
               pStage->m_tIdx, pMsg->m_buff);
               
        pMsg->m_value += 2;
        sprintf(pMsg->m_buff, "MsgID=%d, value%d\n", pMsg->m_msgID, pMsg->m_value);
        
        pStage->m_ready = 0;
        if (pStage->m_next != NULL)
            send(pStage->m_next, (char*)pMsg, pStage->m_act);
            
        pthread_cond_signal(&pStage->m_ready_cond);
    }
}

void create_pipe(pipe_t* pipe, int size)
{
    int i = 0;
    stage_t* pnew = NULL;
    stage_t* head = NULL;
    stage_t* p    = NULL;
    
    if (NULL == pipe)
        return;
        
    pthread_mutex_init(&pipe->m_mutex, NULL);
    pipe->m_stages = size;
    pipe->m_active = 0;
    
    for (i = 0; i < size; i++)
    {
        pnew = (stage_t*)malloc(sizeof(stage_t));
        pthread_mutex_init(&pnew->m_mutex, NULL);
        pthread_cond_init(&pnew->m_ready_cond, NULL);
        pthread_cond_init(&pnew->m_available_cond, NULL);
        pnew->m_ready = 0;
        memset(pnew->m_data, 0, 80);
        pnew->m_next = NULL;
        pnew->m_tIdx = i;
        
        if (i == 0)
        {
            head = pnew;
            p = pnew;
        }
        else
        {
            p->m_next = pnew;
            p = p->m_next;
        }
    }
    
    pipe->m_head = head;
    pipe->m_tail = pnew;
    
    for (p = pipe->m_head; p->m_next != NULL; p = p->m_next)
    {
        pthread_create(&p->m_tid, NULL, handle_message, (void*)p);    
    }
}

int pipe_start(pipe_t* p, char* msg, int nAct)
{
    pthread_mutex_lock(&p->m_mutex);
    p->m_active++;    
    pthread_mutex_unlock(&p->m_mutex);
    
    if (NULL == msg)
    {
        printf("pipe_start: msg is NULL \n");
        return 0;
    }
    send(p->m_head, msg, nAct);
}

int pipe_result(pipe_t* p)
{
    pthread_mutex_lock(&p->m_tail->m_mutex);    
    msg_t* stMsg = (msg_t*) p->m_tail->m_data;
    
    if (stMsg == NULL)
    {
        pthread_mutex_unlock(&p->m_tail->m_mutex);
        return 0;
    }
    
    while(!p->m_tail->m_ready)
    {
        pthread_cond_wait(&p->m_tail->m_available_cond,
                          &p->m_tail->m_mutex);
    }
    
    printf("last tid=%d recv msg=%s\n", p->m_tail->m_tIdx,
           stMsg->m_buff);
           
    memset(&p->m_tail->m_data, 0, 80);
    p->m_tail->m_ready = 0;
    pthread_cond_signal(&p->m_tail->m_ready_cond);
    pthread_mutex_unlock(&p->m_tail->m_mutex);
    
    return 0;
}

int main()
{
    pipe_t* pWF = NULL;    
    char buff[32];
    int nCnt = 0;
    msg_t stMsg;
    
    pWF = (pipe_t*)malloc(sizeof(pipe_t));
    
    pthread_mutex_init(&pWF->m_mutex, NULL);
    pWF->m_head = NULL;
    pWF->m_tail = NULL;
    pWF->m_stages = 0;
    pWF->m_active = 0;
    
    create_pipe(pWF, 5);
    while(1)
    {
        sprintf(stMsg.m_buff, "this is Msg %d\n", nCnt);
        printf("Pipe Start: %d\n", nCnt);
        stMsg.m_value = nCnt;
        stMsg.m_msgID = nCnt;
        pipe_start(pWF, (char*)&stMsg, nCnt);
        nCnt++;
        sleep(2);
        pipe_result(pWF);
    }
    return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值