单进程内简易消息的一种实现:
// 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__