首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

循环负荷高的疑惑

2013-11-15 
循环负载高的疑惑最近公司 上级提了个需求,大体是从一个不断写入的日志中提取有用的信息(很多日志输出行都

循环负载高的疑惑
最近公司 上级提了个需求,大体是从一个不断写入的日志中提取有用的信息(很多日志输出行都是无用的),工作一周左右用C语言写完成了,但跑起来CPU占用了100%(程序要不停跑),现在怀疑是不断的函数调用导致的,如果想减小负载,有什么可行的思路,要单开线程,分工处理么?求大家给个可行的思路,
[解决办法]
如果开线程还是不停循环,中间无任何停顿的话,CPU还是100%;关键问题是不能无停顿的循环,采用定时器、阻塞模式、异步回调等都可以解决。
[解决办法]
调用的时候时不时yeld就行了.
[解决办法]
干过这个,每个循环末尾usleep一下就可以了。

就是扫目录发现新文件就记录到内存里偏移量,每次再去check偏移量变了没,变了就读并修改内存里记录的偏移量。

还用sqlite存了偏移量,怕程序崩溃。
[解决办法]


回调大概怎么写 怎么知道日志更新了,?
你是在哪个平台下,我知道Windows里面对目录、文件监控提供了两个API,它们分别是:FindFirstChangeNotification和ReadDirectoryChangesW。
Linux下监测目录或文件的变化---inotify
[解决办法]
这个开不开线程没有意义吧?

上边说的sleep基本是正解。而监视文件变更的思路则要视你的日志写入频繁程度了,如果日志写入太频繁,监不监视意义不大(不watch都知道它在变)
[解决办法]
参考Microsoft SDK\samples\winbase\IO\fWatch\*.*
[解决办法]
其实你这个需求真的很奇怪了。又想不断地运行、又想cpu占用率降下来?哪有那么好的事情。。
觉得只有当日志没有在记录的时候cpu占用率降下来才比较合理吧?
只要运行的时候整体感觉不卡设计目标就达到了。另外做yield处理的目的多是为了当软件线程数量多于系统可接受的硬件线程数量的时候让多个线程能够自动从并行请求退化成协同模式,而不是为了降低cpu的占用率。
想提取出的日志内容不乱必须要和纪录端做同步才行。
[解决办法]
引用:
Quote: 引用:

可以用Timer来做,周期性的提取即可。

Quote: 引用:

最近公司 上级提了个需求,大体是从一个不断写入的日志中提取有用的信息(很多日志输出行都是无用的),工作一周左右用C语言写完成了,但跑起来CPU占用了100%(程序要不停跑),现在怀疑是不断的函数调用导致的,如果想减小负载,有什么可行的思路,要单开线程,分工处理么?求大家给个可行的思路,


日志刷的很快  C里面没有现成的提取N行的方法呀,,如果用read,日志正在写,那提取的信息就是乱的,,

仅供参考
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <share.h>
#include <conio.h>
int fh;
int c,r;
__int64 offset,offset1,i64,n64,l64,r64;
char ln[16000+1];
int main(int argc,char **argv) {
    if (argc<2) {
        fprintf(stderr,"Usage:%s filename.txt [10]\nto reverse lines of file [default the last 10 lines,-1 for all lines].\n",argv[0]);
        return 1;
    }
    if (argc==2) n64=10i64;
    if (argc>2) sscanf(argv[2],"%I64d",&n64);
    fh=_sopen(argv[1],_O_BINARY
[解决办法]
_O_RDONLY
[解决办法]
_O_RANDOM,_SH_DENYNO);
    if (-1==fh) {
        fprintf(stderr,"Can not _sopen file %s!\n",argv[1]);
        return 2;
    }
    l64=_filelengthi64(fh);if (l64==0i64) {_close(fh);return 0;}
    offset=l64;
    offset1=_lseeki64(fh,-1i64,SEEK_END);
    if (offset1==-1i64) {_close(fh);return 3;}
    i64=0i64;
    while (1) {
        if (_read(fh,&c,1)<1) break;//
        if (('\n'==c && offset1<l64-1i64) 
[解决办法]
 offset1==0i64) {
            if (offset1!=0i64) offset1++;
            if (_lseeki64(fh,offset1,SEEK_SET)==-1i64) break;//


            r64=offset-offset1;
            if (r64<=16000i64) {
                r=_read(fh,ln,(unsigned int)r64);
                if (r<=0) break;//
            } else {
                r=16000;
                while (1) {
                    if (r64>(__int64)r) {
                        r64-=(__int64)r;
                        if (1i64==r64 
[解决办法]
 2i64==r64) {
                            r=8000;
                            r64+=(__int64)r;
                        }
                    } else {
                        r=(int)r64;
                        r64=0i64;
                    }
                    r=_read(fh,ln,r);
                    if (r<=0) break;//
                    if (0i64==r64) break;//
                    ln[r]=0;
                    printf("%s",ln);
                    r=16000;
                }
                if (r<=0) break;//
            }
            ln[r]=0;
            if (r>=2 && ln[r-1]=='\n' && ln[r-2]=='\r') {ln[r-2]='\n';ln[r-1]=0;r--;}//避免输出重定向到文件时行尾多出'\r'
            if (i64==0I64) {
                if ('\n'!=ln[r-1]) printf("%s\n",ln);
                else               printf("%s",ln);
            } else {
                printf("%s",ln);
            }
            i64++;
            if ((i64%10000)==0) cprintf("\r%I64d/%I64d",offset1,l64);
            if (n64>0i64 && i64>=n64) break;//
            offset=offset1;
            _lseeki64(fh,offset1-2i64,SEEK_SET);
            offset1-=2i64;
        } else {
            _lseeki64(fh,-2i64,SEEK_CUR);
            offset1--;
        }
    }
    _close(fh);
    return 0;
}

热点排行