小记

1.搜索文件中含有evutil_make_listen_socket_reuseable,递归查找子目录:

grep evutil_make_listen_socket_reuseable * -2irn

-2同时显示匹配行的上下两行 

-i 忽略大小写 

-n   显示行号

-r  递归查找文件夹子文件

-c 显示匹配的行数


75. libevent回调调用

假设某一时刻多个事件同时触发,如多个连接同时有数据到达、不同连接的事件读写连接同时完成

libevent中只有一个线程执行回调函数,故一次只能处理一个回调,排序靠前的回调没有执行完成,后面所有的回调都得不到执行。


74. libevent静态编译

g++  server.cpp  /usr/lib/libevent.a  -o  server  -lrt

生成的可执行文件server即摆脱库依赖


73. struct bufferevent结构体定义

libevent-2.0.22-stable/include/event2/bufferevent_struct.h:70行

struct bufferevent {
        /** Event base for which this bufferevent was created. */
        struct event_base *ev_base;
        /** Pointer to a table of function pointers to set up how this
            bufferevent behaves. */
        const struct bufferevent_ops *be_ops;

        /** A read event that triggers when a timeout has happened or a socket
            is ready to read data.  Only used by some subtypes of
            bufferevent. */
        struct event ev_read;
        /** A write event that triggers when a timeout has happened or a socket
            is ready to write data.  Only used by some subtypes of
            bufferevent. */
        struct event ev_write;

        /** An input buffer. Only the bufferevent is allowed to add data to
            this buffer, though the user is allowed to drain it. */
        struct evbuffer *input;

        /** An input buffer. Only the bufferevent is allowed to drain data
            from this buffer, though the user is allowed to add it. */
        struct evbuffer *output;

        struct event_watermark wm_read;
        struct event_watermark wm_write;

        bufferevent_data_cb readcb;
        bufferevent_data_cb writecb;
        /* This should be called 'eventcb', but renaming it would break
         * backward compatibility */
        bufferevent_event_cb errorcb;
        void *cbarg;

        struct timeval timeout_read;
        struct timeval timeout_write;

        /** Events that are currently enabled: currently EV_READ and EV_WRITE
            are supported. */
        short enabled;
};
2.memset头文件 #include<string.h> C

                #include<cstring>  C++


3.int evutil_make_listen_socket_reuseable(evutil_socket_t sock) 设置socket重用,成功返回0,失败返回错误码,对所有socket都适用。

4.

 
 
[cpp]  view plain copy
  1. struct bufferevent {  
  2.                struct event_base *ev_base;  
  3.         const struct bufferevent_ops *be_ops;  
  4.         struct event ev_read;  
  5.         struct event ev_write;  
  6.         struct evbuffer *input;  
  7.         struct evbuffer *output;  
  8.         ……  
  9.         bufferevent_data_cb readcb;  
  10.         bufferevent_data_cb writecb;  
  11.         bufferevent_event_cb errorcb;  
  12.         ……  
  13. }  

bufferevent:在struct event 加入加入buffer加入callback,event仅仅具有通知事件可发生的小能力,bufferevent实现了在事件可发生的前提下自动收发数据并且在数据收发完成后自行启动callback进行数据后续处理的大神通。

bufferevent_setcb(struct bufferevent *bufev,readcb,writecb,eventcb,void *ptr)注册回调函数:就是用函数指针给bufferevent结构体成员赋值。

readcb(struct bufferevent,void*)

writecb(struct bufferevent,void*)

eventcb(struct bufferevent,short events,void*)

参数一为触发事件的bufferevent,参数三为bufferevent_setcb的ptr,events是bufferevent上发生的事件类型,目前我只会用BEV_EVENT_CONNECTED 、BEV_EVENT_ERROR 、BEV_EVENT_TIMEOUT。

BEV_EVENT_READING和BEV_EVENT_WRITING并不是在读写事件开始或完成时被触发,目前还不知道怎么用。


5.epoll_wait运行的原理是 :
等侍注册在epfd上的socket fd的事件的发生,如果发生则将发生的sokct fd和事件类型放入到events数组中。 

并 且将注册在epfd上的socket fd的事件类型给清空,所以如果下一个循环你还要关注这个socket fd的话,则需要用epoll_ctl(epfd,EPOLL_CTL_MOD,listenfd,&ev)来重新设置socket fd的事件类型。这时不用EPOLL_CTL_ADD,因为socket fd并未清空,只是事件类型清空。这一步非常重要。

我就是为了这句话才来的。


6.vim替换命令:%s/old/new/g   %表示从第一行到最后一行,s表示替换,g表示整行替换


7.bufferevent_enable(struct bufferevent *bufev,EV_READ) 持久监听bufferevent_getfd(bufev)数据到达。

bufferevent被创建后默认自动激活EV_WRITE。

不激活EV_READ,真的不监听数据接收。

想要在bufferevent关联的socket上接收数据需要如上激活。

EV_READ激活后会持续监听,效果相当于EV_READ | EV_PERSIST。


8.evbuffer_add_buffer(struct evbuffer *dst,struct evbuffer *src) src的数据全给dst,src清空。


9.线程描述符pthread_t为unsigned long int,输出无符号长整形数据printf("%lu\n",pthread_t)。


10.数字转化为字符串、连接字符串:sprintf(char str[30],"%s %d",char str[30],int num)

注意:itoa并不是一个标准的C函数,它是Windows特有的,如果要写跨平台的程序,请用sprintf。


11.  

函数返回值 char * 

但是 空间最好在 外层分配好

函数里面 空间会释放掉的 在函数外面使用 不安全

要不就使用 堆内存 分配


12.设置socket:

#include <sys/types.h>

#include <sys/socket.h>


struct sockaddr_in sin;

memset(&sin,0,sizeof(sin));


sin.sin_family = AF_INET;

sin.sin_addr.s_addr = htonl(INADDR_ANY);

sin.sin_port = htons(8080);


htonl(INADDR_ANY)等价于inet_addr(“0.0.0.0”),表示本机所有地址,在本机网卡有多个或者替换网卡时就不用特意修改了。

inet_addr(“127.0.0.1”)多用于测试使用,telnet 192.168.15.12 8080就会出现“connection refused”。


从sockaddr中取ip和port方法:

struct sockaddr_in sin;

memcpy(&sin,addr,sizeof(sin));


sockaddr和sockaddr_in可以相互类型转换,故简单方法如下:

struct sockaddr_in *sin = (struct sockaddr_in*)addr;


然后:

std::cout<<"ip : "<<inet_ntoa(sin->sin_addr)<<std::endl;
std::cout<<"port : "<<ntohs(sin->sin_port)<<std::endl;


inet_addr头函数#include<arpa/inet.h>  


13.错误号、错误信息头文件:#include<errno.h>


14.C/C++ 字符串转化为整数:atoi   头函数#include<stdlib.h>


15.linux下查看磁盘空间:df -hl


16.CentOS rz sz 安装:sudo yum install lrzsz


17.rpm文件安装:rpm -ivh XXX.rpm


18.tar.bz2解压缩:tar -jxvf xxx.tar.bz2


19.extern可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。


20.new可以这样用?LOCAL_REV_DATA* ptr_recv_data = new LOCAL_REV_DATA;

 typedef struct
{
char buf[DATA_BUFFER_SIZE];
unsigned int len;
int  sfd;
}LOCAL_REV_DATA;


21.int bufferevent_write(struct bufferevent *bufev,const void *data, size_t size);

data指向的长度为size的数据写入bufferevent中的struct evbuffer *outputbufferevent监听socket,在可以发送数据时自动发送数据,数据发送完毕后进入回调函数。

成功返回0,失败返回-1


22.char* buf = "rongxiaojun";

   std::string s(buf,4);

   std::cout<<s<<std::endl;

输出:rong


23.string s = "rong"; s="1"+s+"2"; 但是不可以 s = s+4;


24.if else结构:

if (event & BEV_EVENT_TIMEOUT)

{

LOG4CXX_ERROR(g_logger, "Timed out.");

}

else if (event & BEV_EVENT_EOF)

{

LOG4CXX_ERROR(g_logger, "connection closed.");

}

else if (event & BEV_EVENT_ERROR)

{

LOG4CXX_ERROR(g_logger, "some other error.");

}


25.int event_base_dispatch(struct event_base *base);

无限循环,直到注册事件个数为0,或者event_base_loopbreak() 和 event_base_loopexit()被调用,此时成功退出且返回1。如果循环中有无错,则非正常退出且返回-1


26.

char * s = rongxiaojun;  

warning deprecated converion from string constant to char*

为什么呢?原来char *背后的含义是:给我个字符串,我要修改它。
而理论上,我们传给函数的字面常量是没法被修改的。
所以说,比较和理的办法是把参数类型修改为const char *

改为:const char * s = rongxiaojun;


27.

CTRL+K+F 格式化代码,如果没有自动格式化,说明你的代码有问题
另附上:
CTRL+K+C 注释代码
CTRL+K+U 取消注释代码


28.Libevent关闭socket函数:evutil_closesocket(evutil_socket_t s);


29.

evconnlistener_newevconnlistener_new_bind 用法:

struct evconnlistener *listener  =evconnlistener_new_bind(base,acceptcb,NULL,LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,-1,(struct sockaddr*)&sin,sizeof(sin));

event_base_dispatch(base);

绑定到由sin指定的地址端口,监听连接请求,请求到来即自动连接,然后以listener、新进连接socket、新进连接地址等作为参数调用回调函数。

注意:连接完成后,listener会自动将新进连接socket设置为非阻塞,便于你后续使用。


30.

size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size);

函数从buffereventevbuffer *input中移除size个数据,存储到data,返回实际移除的数据数。


31.

new的用法及函数体外语句:

#include <cstring>

#include <iostream>

std::string *str = new std::string("hello");

int main(){

        const char* buf = "rongxiaojun";

        std::string s(buf,4);

        std::string r = "rong";

        r = "4"+r;

        std::cout<<*str<<std::endl;

}

对比:

#include <cstring>

#include <iostream>

std::string get_str(){

        return "hello";

}

std::string str = get_str();

int main(){

        const char* buf = "rongxiaojun";

        std::string s(buf,4);

        std::string r = "rong";

        r = "4"+r;

        std::cout<<str<<std::endl;

}


32.

struct bufferevent *bufferevent_socket_new(

    struct event_base *base,

    evutil_socket_t fd,

    enum bufferevent_options options);

注意:socket必须是非阻塞,可通过evutil_make_socket_nonblocking函数实现。


33.int evutil_make_socket_nonblocking(evutil_socket_t fd)设置socket非阻塞,成功返回0,失败返回错误码。对所有socket都适用。


34.event_base_loop(base,EVLOOP_NO_EXIT_ON_EMPTY);设置event_base在注册事件为0,循环仍继续,除非调用event_base_loopbreak() 和 event_base_loopexit()


35.

int main(){

        struct event_base *base = event_base_new();

        evutil_socket_t fd = socket(AF_INET, SOCK_STREAM, 0);

        if(evutil_make_socket_nonblocking(fd)){

                std::cout<<"set no block fail"<<std::endl;

                return 1;

        }

        struct bufferevent *bufev = bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE);

        bufferevent_setcb(bufev,NULL,NULL,NULL,NULL);   

        bufferevent_enable(bufev,EV_READ|EV_PERSIST);

        int i = event_base_dispatch(base);

        std::cout<<"event base loop exit"<<std::endl;

}

base上已经通过bufferevent_socket_new(base.....)注册了事件,程序应该陷入event_base_dispatch的无限循环中,但是恰恰相反,它正常退出了,原因不详。


36.查看telnet进程并将其杀死:ps -ef | grep java和 kill -9 2436


37.

socket就是int类型

/* 头文件 */

#include <sys/types.h>

#include <sys/socket.h>

/* 函数原型 */

int socket(intdomain,inttype,intprotocol);


38.

简单的client程序:

int main(){

        struct sockaddr_in sin;

        memset(&sin,0,sizeof(sin));

        sin.sin_family = AF_INET;

        sin.sin_addr.s_addr = inet_addr("127.0.0.1");

        sin.sin_port = htons(8080);

        int fd = socket(AF_INET, SOCK_STREAM, 0);

        if(connect(fd,(struct sockaddr*)&sin,sizeof(sin))<0){

                std::cout<<"connect fail"<<std::endl;

                return 1;

        }

        char buf[50] = {0};

        sprintf(buf,"saldkfjasad");

        if(send(fd,buf,sizeof(buf),0)<0){

               std::cout<<"send fail"<<std::endl;

                return 1;

        }

        int len = recv(fd,buf,sizeof(buf),0);

        buf[len] = '\0';

        std::cout<<buf<<std::endl;

        if(close(fd) != 0)

                std::cout<<"close socket fail"<<std::endl;

}


39.用户通过close()关闭socket1serversocket2bufferevent陷入事件回调函数,触发事件为0X11

#define BEV_EVENT_READING0x01/**< error encountered while reading */

#define BEV_EVENT_WRITING0x02/**< error encountered while writing */

#define BEV_EVENT_EOF0x10/**< eof file reached */

#define BEV_EVENT_ERROR0x20/**< unrecoverable error encountered */

#define BEV_EVENT_TIMEOUT0x40/**< user-specified timeout reached */

#define BEV_EVENT_CONNECTED0x80/**< connect operation finished. */

读过程出错,遇文件结束。

2014.2.11 10:57通过grep BEV_EVENT_EOF * -2irn 取得重大突破:用来检测连接是否关闭的标志事件是 BEV_EVENT_EOF

源码/sample/hello-world.c如下:

static void

conn_eventcb(struct bufferevent *bev, short events, void *user_data)

{

if (events & BEV_EVENT_EOF) {

printf("Connection closed.\n");

} else if (events & BEV_EVENT_ERROR) {

printf("Got an error on the connection: %s\n",

    strerror(errno));/*XXX win32*/

}

/* None of the other events can happen here, since we haven't enabled

 * timeouts */

bufferevent_free(bev);

}


40.grep BEV_EVENT_READING \| BEV_EVENT_TIMEOUT * -2irn

2同时显示匹配行的上下两行 i忽略大小写 n显示行号


41.void event_base_free(struct event_base *base) 释放event_base,注意:此函数并不会替你释放注册在base上的event,也不会关闭event对应的socket及释放它们的指针。


42.浮点数取整函数:

double ceil(double x)  返回大于或者等于指定表达式的最小整数

double floor(double x) 返回小于或者等于指定表达式的最大整数

int m = ceil(2.4);  //m=3

int n = floor(2.4); //m=2

可以这么用。


43.

创建数组:

        pthread_t *threads = new pthread_t[10];

        //int num = sizeof(threads)/sizeof(threads[0]);  这里num=1

        threads[6] = 123;

        for(int i=0;i<10;i++)

                std::cout<<threads[i]<<std::endl;


44.指针数组的创建:

        int **p = new int *[10];

        for(int i=0;i<10;i++)

                p[i] = new int;

        *p[6] = 123;

        for(int i=0;i<10;i++)

                std::cout<<*p[i]<<std::endl;



45.宏定义可以这么用:

#define LEN 1024  

char buffer[LEN] = {0} //宏替换整数


46.std::string str(char *buf); 申请的是栈空间。没有在堆上分配空间,故不需要释放空间。


47.string比较可以直接==

Ifstr == child”) std::cout<<child<<std::endl; 


48.C++ switch case 结构:

switch (x/1000)
{
    case 0:
        cout << x << endl;
        break;
    case 1:
        cout << x * 0.9 << endl;
        break;
}

switch() 括号中的表达式类型:所有能转为int的类型都可以,char可以看做unsigned intbool就是0或者1


49.if-else结构:

        int j = 2;

        if(j == 1){

                std::cout<<1<<std::endl;

        }

        else if(j == 2){

                std::cout<<2<<std::endl;

        }

        else if(j == 3){

                std::cout<<3<<std::endl;

        }


50.数组作形参:

void argu(int a[]){

std::cout<<a[4]<<std::endl;

}

int main(){

int a[10];

a[4] = 12;

argu(a);

}


51.vim 光标放在单词上  shift+* 向下搜索该单词  shift+# 向上搜索该单词


52.枚举类型的使用:

enum{

        DID2USRNAME = 11234,

        USRNAME2DID = 11235,

        DID2DINFO   = 11236,

};

int main(){

int msg_type = 11236;

if(msg_type == DID2DINFO)

std::cout<<enum OK<<std::endl;

}

枚举定义了整数。


宏定义是替换:

#define PI 3.14   //出现PI的地方自动变成3.14,则宏定义实现了数值替换

#define LEN 1024  //同上

#define IP  “192.168.15.12” //出现IP的地方自动变成引号加192.168.15.12,则宏定义实现了字符串替换


53.查找进程:ps -ef | grep deviceInfo

结果:root      3239     1  0 10:46 ?        00:00:00 ./deviceInfo

第一个数字3239即为deviceInfo进程号,kill -9 3239即可杀死。

也可查找进程号对应的进程:ps -ef | grep 3239

结果:root      3239     1  0 10:46 ?        00:00:00 ./deviceInfo


54.C++结构体赋值:

typedef struct{
        int num;
        std::string name;
}info;

int main(){
        info mine;
        mine.num = 14;
        mine.name = "rongxiaojun";

        info him;
        him = mine;

        std::cout<<him.num<<" "<<him.name<<std::endl;

}


55.linux下查看mysql版本:mysql --version


56.函数模板的使用:

template<classT>
T min(T& x,T& y)
{return(x<y)?x:y;}
intmain()
{
int n1 = 2,n2 = 10;
double d1 = 1.5,d2 = 5.6;
    cout<<"较小整数:"<<min(n1,n2)<<endl;
    cout<<"较小实数:"<<min(d1,d2)<<endl;
    system("PAUSE");
    return0;
}

57.安全删除:

template<typename T>

 inline void SafeDeleteArray(T*& p)
{
if (NULL != p)
{
delete[] p;
p = 0;
}
}

template<typename T> 

inline void SafeDelete(T*& p)
{
if (NULL != p)
{
delete p;
p = 0;
}
}

 

int main(){

struct coward *rongxiaojun = new coward;

SafeDelete(rongxiaojun);

}

58.linux下关闭防火墙:service iptables stop

59.evconnlistener_new_bind做四件事:

a.创建socket

b.把socket设置为非阻塞

c.把该socket绑定到参数中指定的地址端口

d.在该socket上监听连接请求

struct sockaddr_in sin;        
memset(&sin,0,sizeof(sin));        
sin.sin_family = AF_INET;        
sin.sin_addr.s_addr = htonl(INADDR_ANY);        
sin.sin_port = htons(8080); 
       
listen_base = event_base_new();      
struct evconnlistener *listener;        
listener = evconnlistener_new_bind(listen_base,acceptcb,NULL,LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,-1,(struct sockaddr*)&sin,sizeof(sin));        
if(!listener){                
	printf("listen or bind fail\n");       
	return -1;        
}

一旦连接到来,自动进行连接,连接完成后启动evconnlistener_new_bind参数中指定的回调函数,并传入如下参数:

a.函数生成的struct evconnlistener指针

b.为新进连接分配的socket

c.struct sockaddr指针,记录对方的地址端口

void acceptcb(struct evconnlistener *listener,evutil_socket_t fd,struct sockaddr *addr,int socklen,void *ptr){}


60.

Linux C语言中 sleep的单位是秒

sleep(5); //5

包含在 <unistd.h>头文件


61.

类静态成员函数只能使用该类中的静态成员变量,只能调用该类中的静态成员函数。否则出现“without object”的错误。


62.

linux下error信息的查看:

#include <errno.h>

int main(){

int fd =socket(AF_INET,SOCK_STREAM,0);

if(fd == -1){

std::cout<<"create socket fail : "<<strerror(errno)<<std::endl;

return 1;

}


63.对方关闭socket,bufferevent触发BEV_EVENT_EOF,并触发事件回调函数,在函数里可以做各种善后。若主动关闭socket,如在读回调或写回调close套接字,相应的事件不会触发,更不会陷入事件回调。


64.

struct bufferevent *bufev = bufferevent_socket_new(base,fd,options);

options为int类型,取值如下:

a.BEV_OPT_CLOSE_ON_FREE1

b.BEV_OPT_THREADSAFE2

c.BEV_OPT_DEFER_CALLBACKS4

d.BEV_OPT_UNLOCK_CALLBACKS8

BEV_OPT_CLOSE_ON_FREE:删除该bufferevent后,一并关闭socket,关闭连接。但是注意bufferevent_free()不会立即删除bufev,它会保留bufev,直到回调函数执行完返回再行删除。

BEV_OPT_THREADSAFE:自动为bufferevent分配一把锁,所以多线程可以同时访问bufferevent。(验证结果不佳,谨慎使用)

仅删除bufferevent、保留socket、保留连接的方法:设置options为0,则删除该bufev,socket仍可被使用。


65.普通指针和静态指针的关系:普通指针可以赋值给静态指针,静态指针不可以赋值给普通指针。

char *ptr;
const char *cptr;

cptr = ptr;  //OK 
ptr = cptr;  //error

静态指针不可以修改变量的值,而普通指针没有任何顾忌。如此静态指针被普通指针赋值,是说明我不会改变变量的值,属于权利的收缩。静态指针赋值给普通指针,相反不可。


66.根据端口号查进程号:lsof -i:12008

结果如下

COMMAND    PID      USER   FD   TYPE   DEVICE  SIZE/OFF   NODE NAME
imDevServ     4208    root       11u   IPv4     29110        0t0              TCP *:accuracer-dbms (LISTEN)


67.压缩文件:zip -r imd.zip imd,将imd文件夹压缩为imd.zip。


68.控制小数点位数:%.nf,想要小数点后几位n就是几。比如说

double res = 45.26978452;

printf("%.3f\n",res); //输出45.269

char temp[10] = {0};

sprintf(temp,"%.2f",res); //temp为“45.26”


69.

kill -9 进程号:根据指定进程号杀死进程   

killall 进程名:根据指定进程名杀死进程


70.

std::cout<<strerror(errno)<<std::endl;

要引入两个头文件errno.h和string.h,errno.h对应errno,string.h对应strerror。


71.

bufferevent_set_timeouts函数原型:

void bufferevent_set_timeouts(struct bufferevent *bufev,

    const struct timeval *timeout_read, const struct timeval *timeout_write


设置读或写的超时时间,bufferevent已经准备好接收数据但对方数据迟迟未到,则经过timeout_read时间后,做两项处理:

A.bufferevent_disable(bufev,EV_READ);

B.触发事件回调函数,并置事件类型为BEV_EVENT_TIMEOUT | BEV_EVENT_READING


经过试验得出如下结论:

A.timeout_read是相对时间。

struct timeval{

int tv_sec;

int tv_usec;

}

设置读超时为4秒,struct timeval tr;  tr.tv_sec = 4;  tr.tv_usec = 0;

C.一旦超时对应的事件便不再被处理。tr超时后,再有数据到达均无任何反应。

D.如果设置超时时间为NULL,则无任何影响。bufferevent_set_timeouts(bufev, &tr, NULL) 读事件被设置超时,写事件不做任何改动。


72.利用core文件进行调试

一、系统默认关闭core的生成,通过ulimit -c unlimited可以暂时启用,但不能一劳永逸。方法如下:

a.vim /etc/profile

b.ulimit -c unlimited

c.echo "/core/core.%p">/proc/sys/kernel/core_pattern

/etc/profile这个文件是每个用户登录时都会运行的环境变量设置,用户登录的时候执行sh脚本的顺序: 

/etc/profile.d/file 
/etc/profile 
/etc/bashrc 
/mingjie/.bashrc 
/mingjie/.bash_profile 

则系统启动后自动执行b和c,则程序一旦崩溃就会在/core/下生成对应的core.pid(如core.3637)文件,供调试使用。

二、gdb ../test core.3637 根据产生的core文件进行gdb调试,只需两个命令:where 和 bt。注意两点:编译程序加-g选项、第一个参数是可执行文件+路径(2014.03.13下午在这里吃亏了),如果不指定路径gdb的结果中所有函数名都变成了??。


----------------------------------------------------------------------------------------------------------------

另外/etc/profile这个文件很有用,定义在里面的shell语句会在用户登录后先执行,所以如果把“service sshd start”定义在里面就不用每次启动系统后都执行一遍上述语句才可xshell连接。

在里面加上一条“echo 草泥马”,系统启动后不会自动跳出一个终端输出“草泥马”,但是每当打开xshell的一个窗口连接进来时都会在窗口顶端输出一条“草泥马”。


取自网络:当你打开一个login shell时,就会加载  /etc/profile~/.profile    /etc/bashrc    ~/.bashrc ,就是打开一个登陆shell。如果不是打开一个登陆shell ,例如 你在console 中 su 成领一个用户。就会得到一个 no login shell   就会用到 /etc/bashrc  ~/.bashrc    而不去取用 /etc/profile  ~/.profile 

关于开机初始化的script   好像就是 /etc/sysinit  vi 看下里面的内容就知道了。


下面是自己实践:

a./etc/rc.d/rc.sysinit和/etc/rc.sysinit之间具有某种联系,修改一个文件另一个也跟着变。

b.在/etc/rc.d/rc.sysinit文件首部加上“ulimit -c unlimited”没有效果,“service sshd start”有效果。

c.在/etc/rc.sysinit文件尾部加,则上述两句均无效果。


-------------------------------------------------------------------------------------------------------------------

发现了一个很有用的命令:source filename

source命令也称为“点命令”,也就是一个点符号(.)。source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。它的作用就是把一个文件的内容当成shell来执行。


分两种情况:

一、使用xshell登陆系统,则每次打开一个窗口登陆进来都会执行一遍/etc/profile里的shell语句。所以不用重启机器,对/etc/profile的修改都会在新窗口体现。

a.如果改了/etc/profile的内容,则已经打开的连接窗口都不会体现新改变。这时如果给/etc/profile加执行权限,./profile,无任何效果。

b.如果改了/etc/profile的内容,然后执行source /etc/profile则这个连接窗口(用户)会体现改变,其他已经登录进来的用户则不会。

二、正常情况下即不使用xshell、直接进系统会怎样呢?修改/etc/profile的内容后,不管新开了几个终端窗口,变化均不会体现,加执行权限后./profile无任何变化,执行source /etc/profile后当前终端体现改变,其他终端均无体现。


所以说修改完/etc/profile后只要source /etc/profile一下就能行了。


-------------------------------------------------------------------------------------------------------------------------

#include <sys/resource.h>


struct rlimit r;

r.rlim_cur = RLIM_INFINITY;

r.rlim_max = RLIM_INFINITY;


if(setrlimit(RLIMIT_CORE, &r) < 0){

std::cout<<"set core fail"<<std::endl;

return -1;

在程序中加入上述语句可以保证当前程序在崩溃时生成core文件。程序运行期间core文件的大小为内核最大值(RLIM_INFINITY),程序结束后,当前xshell和其他xshell值均不受任何影响,还是系统core的默认值0。






grep write\(\) * -4irn


Protobuf是一种高效的序列化协议,可以用于数据交换和数据存储。它的主要优势是大小小,速度快,可扩展性强。下面是使用Protobuf的一些小记: 1. 定义消息格式 首先,需要定义消息格式,以便Protobuf可以将数据序列化和反序列化。消息格式定义在.proto文件中,使用protobuf语言编写。例如,下面是一个简单的消息格式定义: ``` syntax = "proto3"; message Person { string name = 1; int32 age = 2; } ``` 这个消息格式定义了一个名为Person的消息,包含两个字段:name和age。 2. 生成代码 一旦消息格式定义好,就可以使用Protobuf编译器生成代码。编译器将根据消息格式定义生成相应的代码,包括消息类、序列化和反序列化方法等。可以使用以下命令生成代码: ``` protoc --java_out=. message.proto ``` 这将生成一个名为message.pb.java的Java类,该类包含Person消息的定义以及相关方法。 3. 序列化和反序列化 一旦生成了代码,就可以使用Protobuf序列化和反序列化数据。例如,下面是一个示例代码,将一个Person对象序列化为字节数组,并将其反序列化为另一个Person对象: ``` Person person = Person.newBuilder() .setName("Alice") .setAge(25) .build(); byte[] bytes = person.toByteArray(); Person deserializedPerson = Person.parseFrom(bytes); ``` 这个示例代码创建了一个Person对象,将其序列化为字节数组,然后将其反序列化为另一个Person对象。在这个过程中,Protobuf使用生成的代码执行序列化和反序列化操作。 以上是使用Protobuf的一些基本步骤和注意事项,希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值