简单日志系统分为一下几部分
作为输入的submit端,作为输出的domian端,将两端口联系在一起的一片共享内存,以及保存日志的log.txt文件。
submit端作为提交者,负责向共享内存写入日志内容并打印在终端,domain端则将内容读取出来并存放在log.txt中,大体流程如下所示:
任意定义一块空间作为共享内存的首地址#define MASGIC_ID 0xFADECBAC,并申请1001字节大小的空间,定义一个指针p指向首地址,以第0-999位存放内容,第1000位存放r,代表当前读取位置,第1001位存放w,代表当前写入位置,以每100位为一次读写长度。
int shmid=shmget(MASGIC_ID,1002,IPC_CREAT|0777);
char *p = shmat(shmid,NULL,0666);
p[1000]=0;p[1001]=0;
int r=p[1000];
int w=p[1001];
submit端的需求为打印一些字符串内容在终端上,并将这些内容写入存放在共享内存中以便domain端读取,c库的printf无法满足既定要求,所以定义一个myprintf函数来实现。myprintf传入可变参数,即输入量,并将其写在stdout文件中,以实现打印功能。
void MyPrintF( const char * format, ... )
{
char sbuf[64];
va_list args;
va_start (args, format);
vsnprintf (sbuf,64,format, args);
va_end (args);
write(1,sbuf,strlen(sbuf));
.........
随后将sbuf(保存了myprintf打印的内容的数组)的内容写入完整写入到共享内存中,并更新w的数值,domain通过w与r的关系判断共享内存是否有内容,如果有则将其写入到log.txt日志文件中,并更新r的数值。完整代码如下:
//com.h
#ifndef COM_H
#define COM_H
#define MASGIC_ID (0xFADECBAC)
#endif
//submit.c
#include "comm.h"
void MyPrintF( const char * format, ... )
{
char sbuf[64];
va_list args;
va_start (args, format);
vsnprintf (sbuf,64,format, args);
va_end (args);
write(1,sbuf,strlen(sbuf));
int shmid=shmget(MASGIC_ID,1002,IPC_CREAT|0777);
char *p = shmat(shmid,NULL,0666);
int r=p[1000];
int w=p[1001];
printf("r=%d w=%d \n",sizeof(r),w);
stpcpy(&p[w*100],sbuf);
w=(w+1)%10;
p[1001]=w;
shmdt(p);
}
int main(void)
{
int cnt=0,n=9;
while(n--)
{
MyPrintF("good I step into while counter=%d\n",cnt++);
sleep(1);
}
}
//domain.c
#include "comm.h"
int main(void)
{
int fd=open("./log.txt",O_RDWR|O_CREAT|O_TRUNC,0777);
int shmid=shmget(MASGIC_ID,1002,IPC_CREAT|0777);
char *p = shmat(shmid,NULL,0666);
p[1000]=0;p[1001]=0;
while(1)
{
int r=p[1000];
int w=p[1001];
if(r==w)
{
sleep(1);
continue;
}
write(fd,&p[r*100],strlen(&p[r*100]));
r=(r+1)%10;
p[1000]=r;
sleep(1);
}
return 0;
}
该程序功能简单,仅以此作为学习过程的记录。