linux多线程 & IPC【11】《unix网络编程》的系统日志demo

    上一篇自己写的基于共享内存的系统日志服务,有一个缺点就是槽满之后,客户端就阻塞在那里了。当然对于客户端来说,要紧的是去干正事,不是为了打印一行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$ 

下载:



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值