嵌入式学习第二十四天!(进程间通信:消息队列、共享内存、信号灯)

进程间的通信:

  消息队列共享内存信号灯

     1. IPC对象:内存文件

        1. ipcs:

            查看系统中的消息队列,共享内存、信号灯的信息

        2. ipcrm:

            删除消息队列、共享内存、信号灯

ipcrm -Q/-M/-S key
ipcrm -q/-m/-s 消息对立ID/共享内存ID/信号灯ID

1. 消息队列:

    1. 操作流程:

        创建消息队列 -> 发送消息 -> 接收消息

    2. 函数接口:

        1. ftok:
key_t ftok(const char *pathname, int proj_id);

          功能:根据pathname和proj_id生成一个key_t类型的key值,将来可以创建消息队列、共享内存、信号灯

          参数:

              pathename:文件路径

              proj_id:8位非0值

          返回值:

              成功返回key_t类型的IPC对象的key值
              失败返回-1 

        2. msgget:
int msgget(key_t key, int msgflg);

          功能:根据key值对象的IPC对象创建一个消息队列

          参数:

              key:IPC对象名字

              msgflg:IPC_CREAT    对象不存在就创建

                            IPC_EXCL       对象存在报错

                            IPC_CREAT | 0664

          返回值:

              成功返回消息队列ID
              失败返回-1

        3.  msgsnd:
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

          功能:向消息队列中发送消息

          参数:

              msqid:消息队列的ID号

              msgp:发送消息空间的首地址

struct msgbuf
{
    int mtypes;    /* message type, must be > 0 */
    char mtext[1]  /* message data */
};

              msgz:发送消息内容的大小(不包含发送消息类型)

              msgflg:属性,默认位0

          返回值:

              成功返回0 
              失败返回-1 

        4. msgrcv:
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

          功能:从消息队列中接收消息

          参数:

              msqid:消息队列的ID号

              msgp:存放接收到消息空间的首地址

              msgsz:最多接收消息的空间大小

              msgtype:想要接收消息的类型

              msgflg:属性,默认为0

          返回值:

              成功返回实际接收的字节数
              失败返回-1 

        5. msgctl:
int msgctl(int msqid, int cmd, struct msqid_ds *buf);

          功能:向消息队列发送一条cmd命令

          参数:

              msqid:消息队列的ID号

              cmd:IPC_RMID  删除消息队列

              buf:默认传NULL

        练习:

          利用消息队列实现clientA和clientB两个进程任务的全双工聊天功能

clientA.c

 #include "head.h"

key_t key;
int msgid = 0;
pthread_t atob;
pthread_t btoa;

struct msgbuf
{
	long mtype;
	char mtext[256];
};

void *thread_atob(void *arg)
{
	struct msgbuf sndmsg;
	while(1)
	{
		memset(&sndmsg, 0, sizeof(sndmsg));
		sndmsg.mtype = 100;
		gets(sndmsg.mtext);
		msgsnd(msgid, &sndmsg, sizeof(struct msgbuf)-sizeof(long), 0);
		
		if(strcmp(sndmsg.mtext, ".quit") == 0)
		{
			break;
		}
	}
	pthread_cancel(atob);
	return NULL;

}

void *thread_btoa(void *arg)
{
	struct msgbuf recmsg;
	while(1)
	{
		memset(&recmsg, 0, sizeof(recmsg));
		msgrcv(msgid, &recmsg, sizeof(recmsg)-sizeof(long), 200, 0);
		printf("RECV:%s\n", recmsg.mtext);

		if(strcmp(recmsg.mtext, ".quit") == 0)
		{
			break;
		}
	}
	pthread_cancel(btoa);
	return NULL;
}

int main(void)
{
	pthread_create(&atob, NULL, thread_atob, NULL);
	pthread_create(&btoa, NULL, thread_btoa, NULL);

	key = ftok(".", 'a');
	if(key == -1)
	{
		perror("fail to ftok");
		return -1;
	}

	msgid = msgget(key, IPC_CREAT | 0664);
	if(msgid == -1)
	{
		perror("fail to msgget");
		return -1;
	}

	pthread_join(atob, NULL);
	pthread_join(btoa, NULL);
		
	msgctl(msgid, IPC_RMID, NULL);

	return 0;
}

clientB.c

#include "head.h"

key_t key;
int msgid = 0;
pthread_t atob;
pthread_t btoa;

struct msgbuf
{
	long mtype;
	char mtext[256];
};


void *thread_btoa(void *arg)
{
	struct msgbuf sndmsg;
	while(1)
	{
		memset(&sndmsg, 0, sizeof(sndmsg));
		sndmsg.mtype = 200;
		gets(sndmsg.mtext);
		msgsnd(msgid, &sndmsg, sizeof(struct msgbuf)-sizeof(long), 0);
		
		if(strcmp(sndmsg.mtext, ".quit") == 0)
		{
			break;
		}
	}
	pthread_cancel(btoa);

	return NULL;
}

void *thread_atob(void *arg)
{
	struct msgbuf recmsg;
	while(1)
	{
		memset(&recmsg, 0, sizeof(recmsg));
		msgrcv(msgid, &recmsg, sizeof(recmsg)-sizeof(long), 100, 0);
		printf("RECV:%s\n", recmsg.mtext);
		
		if(strcmp(recmsg.mtext, ".quit") == 0)
		{
			break;
		}
	}
	pthread_cancel(atob);
	return NULL;
}

int main(void)
{
	pthread_create(&atob, NULL, thread_atob, NULL);
	pthread_create(&btoa, NULL, thread_btoa, NULL);
	
	key = ftok(".", 'a');
	if(key == -1)
	{
		perror("fail to ftok");
		return -1;
	}

	msgid = msgget(key, IPC_CREAT | 0664);
	if(msgid == -1)
	{
		perror("fail to msgget");
		return -1;
	}

	pthread_join(atob, NULL);
	pthread_join(btoa, NULL);
	
	msgctl(msgid, IPC_RMID, NULL);

	return 0;
}

2. 共享内存:

  进程间通信最高效的形式

  1. 操作方式:

        创建共享内存  ->  映射到共享内存中  ->  共享内存操作  ->  解除映射  ->  删除共享内存

  2. 函数接口:

        1. ftok:
key_t ftok(const char *pathname, int proj_id);

          功能:根据pathname和proj_id生成一个key_t类型的key值,将来可以创建消息队列、共享内存、信号灯

          参数:

              pathename:文件路径

              proj_id:8位非0值

          返回值:

              成功返回key_t类型的IPC对象的key值
              失败返回-1 

        2. shmget:
int shmget(key_t key, size_t size, int shmflg);

          功能:创建一个共享内存

          参数:

              key:IPC对象名称

              size:共享内存的大小

              shmflg:

                    IPC_CREAT

                    IPC_EXCL

          返回值:

              成功返回共享内存ID
              失败返回-1 

        3. shmat
void *shmat(int shmid, const void *shmaddr, int shmflg);

          功能:将一个地址映射到共享内存中

          参数:

              shmid:共享内存ID号

              shmaddr:

                    NULL:让系统选择一个合适的地址映射

                    不为NULL:shmflg设定SHM_RND选择离给定地址最近的能够映射的地址进行映射,否则传递地址为4K的整数倍

        4. shmdt:
int shmdt(const void *shmaddr);

          功能:解除映射

          参数:

              shmaddr:映射的地址

          返回值:

              成功返回0 
              失败返回-1 

        5. shmctl:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

          功能:向共享内存发送命令

          参数:

              shmid:共享内存ID号

              cmd:IPC_RMID 删除共享内存

              buf:NULL

          返回值:

              成功返回0 
              失败返回-1

        练习:

              编写2个进程任务,write.c负责从终端接收字符串写入共享内存中,read.c负责将共享内存中的数据打印在终端

write.c

#include "head.h"

int main(void)
{
	key_t key;
	int shmid;
	char *pshm = NULL;
	
	key = ftok(".", 'a');
	if(key == -1)
	{
		perror("fail to ftok");
		return -1;
	}

	shmid = shmget(key, 4096, IPC_CREAT | 0664);
	if(shmid == -1)
	{
		perror("fail to shmget");
		return -1;
	}
	
	pshm = (char *)shmat(shmid, NULL, 0);
	if(pshm == NULL)
	{
		perror("fail to shmat");
		return -1;
	}
	
	while(1)
	{
		gets(pshm);
		if(!strcmp(pshm, ".quit"))
		{
			shmdt(pshm);
			break;
		}
	}
	shmctl(shmid, IPC_RMID, NULL);

	return 0;
}

read.c

#include "head.h"

int main(void)
{
	key_t key;
	int shmid;
	char *pshm = NULL;
	char *ptmp = NULL;

	key = ftok(".", 'a');
	if(key == -1)
	{
		perror("fail to ftok");
		return -1;
	}

	shmid = shmget(key, 4096, IPC_CREAT | 0664);
	if(shmid == -1)
	{
		perror("fail to shmget");
		return -1;
	}
	
	pshm = shmat(shmid, NULL, 0);
	ptmp = malloc(4096);	
	
	strcpy(ptmp, pshm);

	while(1)
	{
		if (strcmp(pshm, ptmp) == 0)
		{
			continue;
		}
		else
		{
            printf("%s\n", pshm);
            strcpy(ptmp, pshm);
        }

		if(!strcmp(pshm, ".quit"))
		{
			free(ptmp);
			shmdt(pshm);
			break;
		}
	}

	shmctl(shmid, IPC_RMID, NULL);

	return 0;
}

        在这里使用了一个ptmp和原来的pshm比较,从而实现了一个从终端写一个,接收一个,其实应该使用信号灯实现,但是在这里还没有学,所以先暂时使用这个来实现。如果不加判断的话,终端输出的结果如下所示:

        终端会一直持续打印共享内存中的数据,继而需要用到信号灯来实现,写一条,只接收一条

3. 有名信号

  又称为信号灯

  1. 创建:

        semget:
int semget(key_t key, int nsems, int semflg);

          功能:创建一组信号量

          参数:

              key:IPC对象名

              nsems:信号量的个数

              semflg:IPC_CREAT

          返回值:

              成功返回信号量ID
              失败返回-1

  2. 销毁:

        semctl:
int semctl(int semid, int semnum, int cmd, ...);

          功能:向信号灯发送命令

          参数:

              semid:信号灯ID号

              semnum:具体操作信号量的编号

              cmd:

                IPC_RMID    删除信号灯

                SETVAL        设置信号量的值

    初始化:
        union semun {
            int              val;    /* Value for SETVAL */
            struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
            unsigned short  *array;  /* Array for GETALL, SETALL */
            struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                        (Linux-specific) */
        };

  3. 申请/释放信号量:

        semop:
int semop(int semid, struct sembuf *sops, size_t nsops);

          功能:对信号量完成操作

          参数:

              semid:信号灯的ID号

              sops:信号量操作的数组首地址

              nsops:数组元素个数

          返回值:

                成功返回0 
                失败返回-1 

unsigned short sem_num;  /* semaphore number */        操作信号量的下标
short          sem_op;   /* semaphore operation */     具体对信号量的操作(申请:-1  释放:+1)
short          sem_flg;  /* operation flags */         SEM_UNDO

  4. 练习:

        将上面共享内存的练习中加入有名信号,实现写一个字符串,接收一个字符串,实现读和写的同步

write.c

#include "head.h"

int main(void)
{
	key_t key;
	int shmid = 0;
	int semid = 0;
	char *pshmaddr = NULL;
	int val[2] = {0, 1};

	key = ftok(".", 'a');
	if(key == -1)
	{
		perror("fail to ftok");
		return -1;
	}

	semid = semget(key, 2, IPC_CREAT | 0664);
	if(semid == -1)
	{
		perror("fail to semget");
		return -1;
	}
	
	init_sem(semid, val, 2);

	shmid = shmget(key, 4096, IPC_CREAT | 0664);
	if(shmid == -1)
	{
		perror("fail to shmget");
		return -1;
	}

	pshmaddr = shmat(shmid, NULL, 0);
	if(pshmaddr == NULL)
	{
		perror("fail to pshm");
		return -1;
	}
	

	while(1)
	{
		sem_p(semid, 1);
		gets(pshmaddr);
		sem_v(semid, 0);
		if(!strcmp(pshmaddr, ".quit"))
		{
			break;
		}
	}
	
	shmdt(pshmaddr);
	shmctl(shmid, IPC_RMID, NULL);

	return 0;
}

read.c

#include "head.h"

int main(void)
{
	key_t key;
	int shmid = 0;
	int semid = 0;
	char *pshmaddr = NULL;
	int val[2] = {0, 1};

	key = ftok(".", 'a');
	if(key == -1)
	{
		perror("fail to ftok");
		return -1;
	}
	
	semid = semget(key, 2, IPC_CREAT | 0664);
	if(semid == -1)
	{
		perror("fail to semget");
		return -1;
	}
	
	init_sem(semid, val, 2);

	shmid = shmget(key, 4096, IPC_CREAT | 0664);
	if(shmid == -1)
	{
		perror("fail to shmget");
		return -1;
	}

	pshmaddr = shmat(shmid, NULL, 0);
	if(pshmaddr == NULL)
	{
		perror("fail to shmat");
		return -1;
	}

	while(1)
	{
		sem_p(semid, 0);
		printf("%s\n", pshmaddr);
		sem_v(semid, 1);
		if(!strcmp(pshmaddr, ".quit"))
		{
			break;
		}
	}
	
	shmdt(pshmaddr);
	shmctl(shmid, IPC_RMID, NULL);

	return 0;
}

        在这里编写了一个sem.c,实现信号量的初始化init_sem(写信号为1, 读信号为0),申请信号sem_p,释放信号sem_v,同时将所写的函数在head.h中定义,这样read.c和write.c就可以通过头文件head.c调用有名信号量,实现信号的同步。

sem.c

#include "head.h"

int init_sem(int semid, int *pval, int len)
{
	union semun myun;
	int i = 0;
	int ret = 0;


	for(i = 0; i < len; i++)
	{
		myun.val = pval[i];
		ret = semctl(semid, myun.val, SETVAL, myun);
		if(ret == -1)
		{
			perror("fail to semctl");
			return -1;
		}
	}
	
	return 0;
}

int sem_p(int semid, int num)
{
	int ret = 0;
	struct sembuf mybuf;
	
	mybuf.sem_num = num;
	mybuf.sem_op = -1;
	mybuf.sem_flg = SEM_UNDO;
	ret = semop(semid, &mybuf, 1);
	if(ret == -1)
	{
		perror("fail to semop");
		return -1;
	}

	return 0;
}

int sem_v(int semid, int num)
{
	int ret = 0;
	struct sembuf mybuf;

	mybuf.sem_num = num;
	mybuf.sem_op = +1;
	mybuf.sem_flg = SEM_UNDO;
	ret = semop(semid, &mybuf, 1);
	if(ret == -1)
	{
		perror("fail to semop");
		return -1;
	}

	return 0;
}

head.h

#ifndef _HEAD_H_
#define _HEAD_H_

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>

union semun {
	int              val;    /* Value for SETVAL */
	struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
	unsigned short  *array;  /* Array for GETALL, SETALL */
	struct seminfo  *__buf;  /* Buffer for IPC_INFO
								(Linux-specific) */
};


extern int init_sem(int semid, int *pval, int len);
extern int sem_p(int semid, int num);
extern int sem_v(int semid, int num);

#endif

        这里将前面所有所学的知识需要加上的头文件的文件名都加上了,这样以后只用引用head.h即可,方便我们使用,前面代码中的head.h相同

        同时,为了方便我们编译,我们还可以写一个Makefile来帮助我们编译,我们只需要输入make就可以实现gcc read.c sem.c -o read和 gcc write.c sem.c -o write,如下所示:

Makefile

all: write read

write:write.c sem.c
    gcc $^ -o $@
read:read.c sem.c
    gcc $^ -o $@
 
.PHONY:
clean:
    rm write read

        运行结果如上所示,通过有名信号量(信号灯),实现了共享内存的同步操作,所以我们使用共享内存的时候一般都搭配有名信号量来使用。

  • 42
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include #include #include "vxWorks.h" #include "msgQLib.h" #include "taskLib.h" /*#include "memPartLib.h"*/ #include "memLib.h" /*宏定义*/ #define MAX_MSGS (10) /* the length of msg*/ #define MAX_MSG_LEN sizeof(MESSAGE) /*the length of message*/ #define STACK_SIZE 20000 /*the stack size of task*/ #define DELAY_TICKS 50 /*the time of sending message*/ #define MAX_point 5 /*用户从系统内存池中获得内存的最大次数*/ #define size_1 30 /*用户分区的分配的大小*/ #define size_2 40 /*全局变量*/ int tidtask1; int tidtask2; int tidtask3; SEM_ID syncSemId; SEM_ID waitSemId; MSG_Q_ID myMsgQId1; MSG_Q_ID myMsgQId2; MSG_Q_ID myMsgQId3; typedef struct _MESSAGE { int mSendId; /*发送任务 ID*/ int mRecvId; /*接收任务 ID*/ int mData; /*消息中传递的数据*/ char Data[14]; } MESSAGE; /*内存管理*/ char* usermem1; char* usermem2; MESSAGE *point1[MAX_point]; MESSAGE *point2[MAX_point]; MESSAGE *point3[MAX_point]; int point1_index=0; int point2_index=0; int point3_index=0; PART_ID partid1; PART_ID partid2; #define MID_MESSAGE(id) (id) /*函数声明*/ int start(void); int task1(void); int task2(void); int task3(void); template T* mymalloc(unsigned nBytes); void myfree(void); void bye(void); /***************************************[progStart]*******************************************/ /*启动程序,创建息队例,任务*/ int start(void) { tidtask1=taskSpawn("tTask1", 220, 0, STACK_SIZE, (FUNCPTR)task1,0,0,0,0,0,0,0,0,0,0); usermem1=malloc(200); partid1=memPartCreate(usermem1,200); usermem2=malloc(400); partid2=memPartCreate(usermem2,400); return; } /**************************************[test_end]********************************************/ /*是否相等,相等返回1*/ int test_end(char *end,char *target) { int ret; if(!strcmp(end,target)) ret=1; else ret=0; return ret; } /****************************************[task1]***********************************************/ /*管理Task。负责系统启动时同步系统中其他Task的启动同步,利用信号量的semFlush()完成。同时接收各*/ /*Task的告警信息,告警信息需编号以logmsg方式输出。本task负责系统结束时的Task删除处理*/ int task1(void) { int singal; int message; MESSAGE *rxMsg=mymalloc(26); /*define messages,and alloc memory*/ memset(rxMsg,0,26); syncSemId=semBCreate(SEM_Q_FIFO,SEM_EMPTY); /*creat semaphore*/ waitSemId=semBCreate(SEM_Q_PRIORITY,SEM_EMPTY); myMsgQId1=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_PRIORITY); /*create msgQ*/ myMsgQId2=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_PRIORITY); myMsgQId3=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_PRIORITY); tidtask2=taskSpawn("tTask2", 200, 0, STACK_SIZE, (FUNCPTR)task2,0,0,0,0,0,0,0,0,0,0); /*create task*/ tidtask3=taskSpawn("tTask3", 210, 0, STACK_SIZE, (FUNCPTR)task3,0,0,0,0,0,0,0,0,0,0); printf("Please input one of the following commands:add,sub,multiply,divide,testcommand\n"); /*the command we should put into the console*/ semFlush(syncSemId); /*release semaphore*/ semGive(waitSemId); while(1) { singal=1; msgQReceive(myMsgQId1,(char*)&rxMsg,sizeof(rxMsg),WAIT_FOREVER); if(rxMsg->mRecvId==MID_MESSAGE(3)) /*receive MsgQ from task3*/ { singal=test_end(rxMsg->Data,"wrong length")-1; logMsg("task3 receiveing a:%s\n",rxMsg->Data); /*put the warn from task3*/ logMsg("Please reput the other command!\n"); msgQReceive(myMsgQId1,(char*)&rxMsg,MAX_MSG_LEN,WAIT_FOREVER); /*recive MsgQ from task3*/ } if(rxMsg->mRecvId==MID_MESSAGE(2)) /*receive MsgQ from task2*/ { message=test_end(rxMsg->Data,"sysend"); if(message) { /*if the message from task2 is "sysend" and did not receive the warn from task3, close the system*/ if(singal) { bye(); } } else {/*if the message from task2 is "sysend" and receive the warn from task3, reput the command*/ if(singal) logMsg("task2 receiveing a %s\n",rxMsg->Data); logMsg("please reput the correct command!\n"); } } } return; } /********************************************************************************************/ int change_buf(char *command) { int ret; if(!strcmp(command,"add")) ret=1; else if(!strcmp(command,"sub")) ret=2; else if(!strcmp(command,"multiply")) ret=3; else if(!strcmp(command,"divide")) ret=4; else if(!strcmp(command,"testcommand")) ret=5; else ret=0; return ret; } /****************************************[task2]*********************************************/ /*console 命令行接收Task。接收并分析console发来的命令行及参数。自行设置5种以上命令,并根据命*/ /*令的内容向Task3发送激励消息。同时实现系统退出命令,使系统采用适当方式安全退出。收到非法命令*/ /*向Task1告警*/ int task2(void) { char buf[100]; int command; char *str=mymalloc(35); MESSAGE *txMsg=mymalloc(26); memset(str,0,35); memset(txMsg,0,26); txMsg->mSendId=MID_MESSAGE(2); txMsg->mRecvId=MID_MESSAGE(2); FOREVER { semTake(syncSemId,WAIT_FOREVER); semTake(waitSemId,WAIT_FOREVER); gets(buf); command=change_buf(buf);/*change the commands into numbers*/ switch(command) { case 0:/*receive uncorrect command*/ txMsg->mData=0; strcpy(txMsg->Data,"wrong command");/*send warn to task1*/ msgQSend(myMsgQId1,(char*)&txMsg,sizeof(txMsg),WAIT_FOREVER,MSG_PRI_NORMAL); break; case 1:/*receive add command*/ strcpy(str,"This an add caculate!\0"); txMsg->mData=1; break; case 2:/*receive sub command*/ strcpy(str,"This a sub caculate!\0"); txMsg->mData=2; break; case 3:/*receive multiply command*/ strcpy(str,"This a multiply caculate!\0"); txMsg->mData=3; break; case 4:/*receive divide command*/ strcpy(str,"This a divide caculate!\0"); txMsg->mData=4; break; case 5:/*receive testcommand,send a long string to task3*/ strcpy(str,"This a testcommand to warn task1!\0"); txMsg->mData=5; break; default: break; } if(txMsg->mData!=0) {/*send along string to task3,and send a message to taks3*/ msgQSend(myMsgQId3,(char*)&str,sizeof(str),WAIT_FOREVER,MSG_PRI_NORMAL); msgQSend(myMsgQId3,(char*)&txMsg,sizeof(txMsg),WAIT_FOREVER,MSG_PRI_NORMAL); } semGive(waitSemId); semGive(syncSemId); taskDelay(DELAY_TICKS); if(txMsg->mData!=0) {/*send sysend to task1 to let task1 close system*/ strcpy(txMsg->Data,"sysend"); msgQSend(myMsgQId1,(char*)&txMsg,sizeof(txMsg),WAIT_FOREVER,MSG_PRI_NORMAL); } } return; } /****************************************[task3]********************************************/ /*console输出Task。接收需打印输出的字串消息(命令),输出到console。收到长度为0或超常字串向*/ /*Task1告警*/ int task3(void) { int firstData=100; int secondData=10; MESSAGE *rxMsg=mymalloc(26); MESSAGE *txMsg=mymalloc(26); char *rstr=mymalloc(35); memset(txMsg,0,26); memset(txMsg,0,26); memset(rstr,0,35); txMsg->mSendId=MID_MESSAGE(3); txMsg->mRecvId=MID_MESSAGE(3); while(1) { semTake(syncSemId,WAIT_FOREVER); msgQReceive(myMsgQId3,(char*)&rstr,sizeof(rstr),WAIT_FOREVER); if(strlen(rstr)=26) {/*make sure whether the string is too long or short*/ strcpy(txMsg->Data,"wrong length"); msgQSend(myMsgQId1,(char*)&txMsg,sizeof(txMsg),WAIT_FOREVER,MSG_PRI_NORMAL); /*msgQReceive(myMsgQId3,(char*)&rxMsg,sizeof(rxMsg),WAIT_FOREVER);*/ } semTake(waitSemId,WAIT_FOREVER); msgQReceive(myMsgQId3,(char*)&rxMsg,sizeof(rxMsg),WAIT_FOREVER); if(rxMsg->mData!=5) {/*when it is not testcommand,printf these*/ printf("%s\n",rstr); printf("there are two datas!\n"); printf("firstData:100\n"); printf("secondData:10\n"); } switch(rxMsg->mData) { case 1:/*printf add caculate*/ printf("The result is:%d\n",firstData+secondData); break; case 2:/*printf sub caculate*/ printf("The result is:%d\n",firstData-secondData); break; case 3:/*printf multiply caculate*/ printf("The result is:%d\n",firstData*secondData); break; case 4:/*printf divide caculate*/ printf("The result is:%d\n",firstData/secondData); break; case 5: break; default: break; } semGive(waitSemId); semGive(syncSemId); taskDelay(DELAY_TICKS); } return; } template T* mymalloc(unsigned nBytes) { T* point; int i=0; /*用户分区一是否能分配的标志位*/ int j=0; /*用户分区二是否能分配的标志位*/ if(nBytes=size_1 && nBytes=size_2) && point3_index<MAX_point) /*若用户分区二不能分配,由系统内存池来分配,且只能从系统内存池中分配MAX_point次*/ { point=malloc(nBytes); point3[point3_index]=point; printf("the number of the point3_index is:%d\n",point3_index); point3_index++; } return point; } void myfree(void) { int i=0; for (i=0;i<point1_index;i++) { memPartFree(partid1,point1[i]); } for (i=0;i<point2_index;i++) { memPartFree(partid2,point2[i]); } for (i=0;i<point3_index;i++) { free(point3[i]); } free(usermem1); free(usermem2); printf("The memory have freed!\n"); } void bye(void) { myfree(); logMsg("Bye-bye\n"); taskDelete(tidtask2); taskDelete(tidtask3); msgQDelete(myMsgQId1); msgQDelete(myMsgQId2); msgQDelete(myMsgQId3); semDelete(syncSemId); taskDelete(tidtask1); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值