单进程内简易消息的一种实现

单进程内简易消息的一种实现:

// main.cpp
#include "main.h"

#define MY_HEAP_SIZE (1024 * 1024) // 堆空间1M

MESSAGELIST *msgtestlist;
pthread_mutex_t mainMutex;
int mainLock = 1; // 进程卡住
pthread_cond_t mainCond; // 主进程条件变量

void ExitMain()
{
    mainLock = 0;
    pthread_cond_signal(&mainCond);
    return;
}

void *mymsgtest1(void *arg) // 入口函数
{
    while(1) {
        recvmsg(0);
//        sleep(1);
//        printf("1111\n");
    }
    return NULL;
}
int breath = 0;
int test1func(MESSAGE *msg) // 工作线程1
{
    printf("it is test1\n");
        sleep(1);
        breath++;
        if (breath > 5) {
            printf("killing\n");
            ExitMain();
        }
    MESSAGE sendMsg;
    sendMsg.taskid = 2;
    sendMsg.msgid = 1;
    if (msg->msgid == 1) {
        if (sendmsg(&sendMsg) != 0) {
            printf("send msg fail,totask%d\n", sendMsg.taskid);
        }
    }
    return 0;
}

void *mymsgtest2(void *arg) // 入口函数
{
    while(1) {
        recvmsg(1);
//        sleep(1);
//        printf("2222\n");
    }
    return NULL;
}

int test2func(MESSAGE *msg) // 工作线程2
{
    printf("it is test 2\n");
    sleep(1);
    MESSAGE sendMsg;
    sendMsg.taskid = 1;
    sendMsg.msgid = 1;
    if (msg->msgid == 1) {
        if (sendmsg(&sendMsg) != 0) {
            printf("send msg fail,totask%d\n", sendMsg.taskid);
        }
    }
    return 0;
}

TASKINFO msgtaskinfo[] = {
    { 1 , MY_HEAP_SIZE, test1func, mymsgtest1},
   {2, MY_HEAP_SIZE, test2func, mymsgtest2}
};

int initmsglist(TASKINFO *tasklist) // 初始化消息列表
{
    int tasknum = sizeof(msgtaskinfo) / sizeof(TASKINFO);
    int i = 0;
    msgtestlist = (MESSAGELIST*)malloc(sizeof(MESSAGELIST) * tasknum);
    printf("%p\n", msgtestlist);
    memset(msgtestlist, 0, sizeof(msgtestlist)); // memset 没有返回值

    for (i = 0; i < tasknum; i++) {
        msgtestlist[i].taskid = msgtaskinfo[i].taskid;
        printf("i = %d, taskid =%d\n", i, msgtestlist[i].taskid);
        pthread_cond_init(&msgtestlist[i].pthreadcond, NULL);
        msgtestlist[i].func_work = tasklist[i].pthread_fun_work;
        pthread_mutex_init(&msgtestlist[i].pthreadmutex, NULL);
        msgtestlist[i].flags = 0;
    }
    return 0;
}

int sendmsg(MESSAGE *msg)
{
    int i = 0;
    if (msg == NULL) {
        printf("send msg fail, msg is NULL");
        return 1;
    }

    for (i = 0; i < sizeof(msgtaskinfo) / sizeof(TASKINFO); i++) {
        if (msg->taskid == msgtestlist[i].taskid) {
            pthread_mutex_lock(&msgtestlist[i].pthreadmutex); // 获取锁
            memcpy(&msgtestlist[i].messagebuf, msg, sizeof(MESSAGE));
            msgtestlist[i].flags++;

            pthread_cond_signal(&msgtestlist[i].pthreadcond);

            pthread_mutex_unlock(&msgtestlist[i].pthreadmutex); // 释放锁,释放后接收端才能获取锁
        }
    }
    printf("send success, totask%d\n", msg->taskid);
    return 0;
}

void recvmsg(int taskid)
{
    int i = 0;
    func_dosomething func = NULL;
    MESSAGE msgbuffer = {0};
    if (1) {
        pthread_mutex_lock(&msgtestlist[taskid].pthreadmutex); // 获取锁
        pthread_cond_wait(&msgtestlist[taskid].pthreadcond, &msgtestlist[taskid].pthreadmutex); // 沉睡线程,以免占用cpu
        msgtestlist[taskid].flags--; // 将线程flag恢复空;
        memcpy(&msgbuffer, &msgtestlist[taskid].messagebuf, sizeof(MESSAGE));
        pthread_mutex_unlock(&msgtestlist[taskid].pthreadmutex); // 释放锁,发送端才能继续发过来

        msgtestlist[taskid].func_work(&msgbuffer);
        }
    return;
}

int CreateOneTaskThread(TASKINFO *taskinfo)
{
    pthread_t thread;
    pthread_attr_t attr;
    if (pthread_attr_init(&attr) != 0) { // 初始化线程属性
        printf("attr init fail\n");
    }
    
    // pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
    size_t stacksize = (size_t)taskinfo->stacksize;
    if (pthread_attr_setstacksize(&attr, stacksize) != 0) // 设置堆栈大小
    {
        printf("setstack fail , use default value");
    }

    if (pthread_create(&thread, NULL, taskinfo->pthrad_func, NULL) != 0) {
        printf("create task %d fail\n", taskinfo->taskid);
        return 1;
    }
    printf("create task %d\n", taskinfo->taskid);
    pthread_detach(thread);
    // if (pthread_join(thread, NULL) != 0) {
    //     printf("join fail, taskid = %d\n", taskinfo->taskid);
    // }
    pthread_attr_destroy(&attr);
    return 0;
}


int main()
{
    int i = 0;
    pthread_cond_init(&mainCond, NULL);
    pthread_mutex_init(&mainMutex, NULL);
    if (initmsglist(msgtaskinfo) != 0) {
        printf("init msglist fail\n");
        return 1;
    }
    for (i = 0; i < sizeof(msgtaskinfo) / sizeof(TASKINFO); i++) {
        if (CreateOneTaskThread(&msgtaskinfo[i]) != 0) {
            printf("create task %d fail\n", msgtaskinfo[i].taskid);
        }
    }
    sleep(1);
    MESSAGE msg;
    msg.taskid = 1;
    msg.msgid = 1;
    printf("come here\n");
    if (msg.msgid == 1) {
        if (sendmsg(&msg) != 0) {
            printf("send msg fail,totask%d\n", msg.taskid);
        }
    }
    pthread_mutex_lock(&mainMutex);
    while (mainLock) {
        pthread_cond_wait(&mainCond, &mainMutex);
    }
    pthread_mutex_unlock(&mainMutex);
    pthread_cond_destroy(&mainCond); // 销毁进程
    printf("come here2\n");
    return 0;
}

进程内:

// main.h
#ifndef MAIN_H__
#define MAIN_H__
#ifdef __cplusplus  
extern "C"{
#endif

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

typedef struct MESSAGE {
    int taskid; // 接收方的taskid
    int submsgid;
    int msgid;
    int param1;
    int param2;
} MESSAGE;
typedef void* (*func)(void *arg); // 入口函数

typedef int (*func_dosomething)(MESSAGE *msg); // 处理函数



// 消息列表结构体
typedef struct msginitstruct {
    pthread_mutex_t pthreadmutex;
    MESSAGE messagebuf;
    pthread_cond_t pthreadcond;
    func_dosomething  func_work;
    int taskid;
    int flags;
} MESSAGELIST;

// task info list
typedef struct taskinfo {
    int taskid; // 任务ID
    int stacksize; // 设置堆栈大小
    func_dosomething pthread_fun_work; // 工作线程
    func pthrad_func; // 入口线程
} TASKINFO; 

int sendmsg(MESSAGE *msg);
void recvmsg(int taskid);



#ifdef __cplusplus  
}
#endif

#endif // !MAIN_H__

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值