上一篇自己写的基于共享内存的系统日志服务,有一个缺点就是槽满之后,客户端就阻塞在那里了。当然对于客户端来说,要紧的是去干正事,不是为了打印一行log神经病一样阻塞在这里。所以阻塞不是好的解决方案,应该:
【1】分配较大的NMSG
【2】服务器响应及时,这样即使消息多,也能很快处理完,不至于积累下来。
【3】在槽满时,再有消息来的话,给出overflow
书本上就是用了overflow,这部分还没有细看。
服务器端:s.c
#include "a.h"
int main(int argc, char *argv[])
{
int fd, index, lastnoverflow, temp;
long offset;
struct shmst *ptr;
if(argc!=2)
{
printf("Usage: ser <name>");
exit(2);
}
shm_unlink(argv[1]);
fd=shm_open(argv[1], O_RDWR|O_CREAT|O_EXCL,S_IRUSR | S_IWUSR);
ptr=mmap(NULL,sizeof(struct shmst),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
ftruncate(fd,sizeof(struct shmst));
close(fd);
for(index=0;index<NMSG;index++)
{
ptr->msgoff[index]=index*MSGSIZE;
}
sem_init(&ptr->mutex,1,1);
sem_init(&ptr->nempty,1,NMSG);
sem_init(&ptr->nstored,1,0);
sem_init(&ptr->noverflowmutex,1,1);
index=0;
lastnoverflow=0;
while(1)
{
sem_wait(&ptr->nstored);
sem_wait(&ptr->mutex);
offset=ptr->msgoff[index];
printf("index= %d :%s\n", index, &ptr->msgdata[offset]);
if(++index>=NMSG)
index=0;
sem_post(&ptr->mutex);
sem_post(&ptr->nempty);
sem_wait(&ptr->noverflowmutex);
temp=ptr->noverflow;
sem_post(&ptr->noverflowmutex);
if(temp!=lastnoverflow)
{
printf("noverflow = %d\n",temp);
lastnoverflow=temp;
}
}
exit(0);
}
客户端:
#include "a.h"
int main(int argc, char *argv[])
{
int fd,i,nloop=50,nusec=0;
pid_t pid;
char msg[MSGSIZE];
long offset;
struct shmst *ptr;
if(argc!=2)
{
printf("Usage: cc <name>\n");
exit(2);
}
fd=shm_open(argv[1], O_RDWR, S_IRUSR | S_IWUSR);
ptr=mmap(NULL,sizeof(struct shmst),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
close(fd);
pid=getpid();
for(i=0;i<nloop;i++)
{
usleep(100);
snprintf(msg,MSGSIZE,"pid %d: msg %d", (long)pid, i);
if(sem_trywait(&ptr->nempty)==-1)
{
if(errno==EAGAIN)
{
sem_wait(&ptr->noverflowmutex);
ptr->noverflow++;
sem_post(&ptr->noverflowmutex);
continue;
}
else
{
printf("sem_trywait error");
}
}
sem_wait(&ptr->mutex);
offset=ptr->msgoff[ptr->nput];
if(++(ptr->nput)>=NMSG)
ptr->nput=0;
sem_post(&ptr->mutex);
strcpy(&ptr->msgdata[offset],msg);
sem_post(&ptr->nstored);
}
exit(0);
}
头文件:
#ifndef _A_H_
#define _A_H_
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>
#include <semaphore.h>
#define MSGSIZE 256
#define NMSG 16
#define FILE_MODE 777
struct shmst
{
sem_t mutex;
sem_t nempty;
sem_t nstored;
int nput;
long noverflow;
sem_t noverflowmutex;
long msgoff[NMSG];
char msgdata[NMSG * MSGSIZE];
};
#endif
编译脚本:
#!/bin/sh
gcc c.c -o cc -lrt -g -lpthread
gcc s.c -o ss -lrt -g -lpthread
运行:
administrator@ubuntu:~/test/po$ ./ss name &
[2] 3821
administrator@ubuntu:~/test/po$ jobs
[1]- 运行中 ./log_server & (工作目录:~/test/log_test)
[2]+ 运行中 ./ss name &
administrator@ubuntu:~/test/po$ ./cc name
index= 0 :pid 3822: msg 0
index= 1 :pid 3822: msg 1
index= 2 :pid 3822: msg 2
index= 3 :pid 3822: msg 3
index= 4 :pid 3822: msg 4
index= 5 :pid 3822: msg 5
index= 6 :pid 3822: msg 6
index= 7 :pid 3822: msg 7
index= 8 :pid 3822: msg 8
index= 9 :pid 3822: msg 9
index= 10 :pid 3822: msg 10
index= 11 :pid 3822: msg 11
index= 12 :pid 3822: msg 12
index= 13 :pid 3822: msg 13
index= 14 :pid 3822: msg 14
index= 15 :pid 3822: msg 15
index= 0 :pid 3822: msg 16
index= 1 :pid 3822: msg 17
index= 2 :pid 3822: msg 18
index= 3 :pid 3822: msg 19
index= 4 :pid 3822: msg 20
index= 5 :pid 3822: msg 21
index= 6 :pid 3822: msg 22
index= 7 :pid 3822: msg 23
index= 8 :pid 3822: msg 24
index= 9 :pid 3822: msg 25
index= 10 :pid 3822: msg 26
index= 11 :pid 3822: msg 27
index= 12 :pid 3822: msg 28
index= 13 :pid 3822: msg 29
index= 14 :pid 3822: msg 30
index= 15 :pid 3822: msg 31
index= 0 :pid 3822: msg 32
index= 1 :pid 3822: msg 33
index= 2 :pid 3822: msg 34
index= 3 :pid 3822: msg 35
index= 4 :pid 3822: msg 36
index= 5 :pid 3822: msg 37
index= 6 :pid 3822: msg 38
index= 7 :pid 3822: msg 39
index= 8 :pid 3822: msg 40
index= 9 :pid 3822: msg 41
index= 10 :pid 3822: msg 42
index= 11 :pid 3822: msg 43
index= 12 :pid 3822: msg 44
index= 13 :pid 3822: msg 45
index= 14 :pid 3822: msg 46
index= 15 :pid 3822: msg 47
index= 0 :pid 3822: msg 48
index= 1 :pid 3822: msg 49
administrator@ubuntu:~/test/po$
下载: