POSIX 学习笔记---工作流

来源:互联网 发布:stm8 ubuntu 编辑:程序博客网 时间:2024/06/13 09:56

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




原创粉丝点击