c/c++/gcc
来源:互联网 发布:专业手机数据恢复 编辑:程序博客网 时间:2024/05/17 20:28
gdb
生成core文件的条件 -g // gcc -g main.c -o exe ulimit -c 1024 // ulimit -a 权限问题:exe文件的拥有者,否则可能不能生成core文件。 // 用root, 不用sudo。sudo没有打印“core dumped"core文件的相关信息 默认位置:同exe文件的位置,若程序中有chdir(),则有可能改变。 默认名字:core 可以通过 /proc/sys/kernel/core*,等配置文件修改 // echo 1 > core_uses_pid查看相应的exe文件: file coreFile gdb -c coreFile readelf -h coreFile利用core分析程序问题: gdb -c coreFile exeFile gdb exeFile coreFile backtrace, bt 2(打印2层栈)gdb的使用 开启:gdb exeFile 给exe文件传入参数:set args/run -t 5 -i data/rtp.data 查看代码:set/show listsize, list +/-, list 151, list funcName, list 45, 49 (gdb) list wiucs::RecordConvert::convert 打断点:break 151; b filename:151; b WebmMuxer::open; break 199 if x == 2(x若是局部变量,则需要到此代码处,再打断点) watch x > 2(x处理同上,x>2的值若有改变,则断点产生) 断点管理:delete 4(断点号), disable/enable 4, clear 151(代码行号), tbreak 151 查看变量:print varName; display/undisplay varName(遇断点时,自动显示); whatis mediaHead(查看结构体); set print pretty on (gdb) p ntohs(seqnum) 控制流程:run, next, step(into func), finish(outof func), continue/until 159, 改流程:return 111, jump 159(直接跳到159行), signal 11(发段错误信息使程序停止执行) 设置值:set variable var_p = (char *)malloc(2) or print var_p = ... 线程:thread 3(切换到线程3); break 88 thread 3 if x == y // 当线程3执行到88行并且变量x和y值相等时中断 查看信息:where, frame 9(进入9号帧), up / down-silently(上下移动帧), info locals/args/threads/frame/line(当前帧下的信息) (gdb) info all-registers 寄存器中放置了程序运行时的数据,比如程序当前运行的指令地址(ip),程序的当前堆栈地址(sp) (gdb) disassemble func // 打印出汇编代码gdb问题: 有断点停不下来 // 实际停下来了,只是按continue时,没有返回,又按了一次,导致C两次,断点打印在前面
gcc 寻找头文件
1. 当前文件夹; 2. -I ; 3. /usr/include 4. gcc的环境变量C_INCLUDE_PATH...#include <系统路径> // 查找顺序 3, 4, 1, 2 #include “对此C文件的路径” // 查找顺序 1,2,3,4
生成静态库
1. gcc -c a.c // 编译成.o// ar命令中不能加-lXXX, ar: two different operation options specified2. ar -rcs libXXX.a obj1.o obj2.o (ar=archive, r=replace, c=create, s=)
生成动态库
gcc -fPIC -shared -o libxxx.so a.c b.c gcc -fPIC -o a.o -c a.c // gcc -c a.c gcc -shared -o libxxx.so a.o // gcc -fPIC -shared -o libXXX.so a.o
查看库中的内容
ar tv libXXX.a // 查看静态库含有的.o文件nm -s libXXX.a // 查看静态动态库中的.o以及函数: U引用 T定义 W弱态ldd libXXX.so // 查看so中的引用的so
库的使用
1. -L; 2. LD_LIBRARY_PATH; 3. /etc/ld.so.conf ---> ldconfig ---> ld.so.cache; 4. /lib, /usr/lib静态库:编译时寻找的顺序:1,2,3,4; 编译完成后.a的代码集成在exe中,执行时无需.a文件了。动态库:编译时寻找的顺序同上; 执行时仍然需要.so,其查找顺序为: -Wl,-rpath,/path1/:/path2(无空格,冒号),2,3,4
Q&A
0. LD_LIBRARY_PATH已经包含了动态库所需要的路径,但是程序还是找不到所需要的库 场景1:LD_LIBRARY_PATH=...:A:...:B:... A,B路径都包含libjvm.so, libjava.so , 但是B=$JAVA_HOME/jre/lib/amd64/ 结果:程序只在A中找所有需要的jre库 Error occurred during initialization of VM Unable to load native library: /opt/wiucs-cvt/libjava.so: cannot open shared object file: No such file or director 解决方法: A,B位置互换; 或者删除A中的.so 场景2:export LD_LIBRARY_PATH=/tmp; 当前shell调用 httpd, httpd 的子进程执行CGI程序,CGI程序需要新的SO 结果:尽管/tmp下有所需要的动态库,但是CGI仍然引用不到 解决方法:export后仅當前shell(控制台)及其子shell(httpd)可用,CGI是httpd的子进程所以引用不到; 指定执行动态库时的搜索路径: mips2_fp_le-gcc -o getPageInfo -Wl,-rpath,/tmp $(OBJS) $(LIBS) 1. 多个-l的顺序:根据依赖关系,反序排列! g++ -o test IsacDecoder.cpp... -I... -L... -liSAC -lCNG -lsignal_processing -lpthread2. 找不到库中函数:nfs: server is working? // 动态库在nfs server上3. 程序既要和libhello进行静态连接,又要和libbye进行动态连接, 其命令应为: gcc testlib.o -o exefile -WI,-Bstatic -lhello -WI,-Bdynamic -lbye -static -lXXX // 强制使用静态库(同时存在,默认动态库优先) 4. 动态库的应用:做插件 plugin // dlopen, dlsym
gcc 命令
gcc -o hello hello.c -save-temps(一步,保留中间文件)预处理 gcc -o hello.i -E hello.c编译和汇编 gcc -o hello.o -c hello.i // ccl and as链接 gcc -o hello hello.o // ld 生成依赖关系 gcc -MM a.c // a.o: a.c; -MMD: 生成.d .o -Dmacro 相当于C语言中的#define macro -Dmacro=defn 相当于C语言中的#define macro=defn 调试打印 #gcc -DDLD_DEBUG -O0 -g3 -Wall -c #ifdef DLD_DEBUG#define dbprintf(fmtstr, args...) \{printf(fmtstr, ##args); printf("\n");}#else#define dbprintf(fmtstr, args...)#endif
基本
0. 工具:Enterprise architecture 1. 可执行文件的执行时间 time ./test2. 一般的系统都把内核源码放在/usr/src下面3. #include <math.h> -lm 一定要加上 4. could not read symbols: Malformed archive libCNG.a 移动位置后 失效 ?5. case UE_KEY_SK01 ... UE_KEY_SK06: ??6. static: C中表示本地文件,不能被异地引用 && 多次重入函数时引用上次保存的值 类中static 的数据,需要在外部进行初始化,因为只能有一份。 singleObj* singleObj::_Obj = NULL;7. yasm是汇编编译器:为了提高效率用到了汇编指令的程序需要yasm8. 结构体中的指定初始化 struct { char exten[AST_MAX_EXTENSION]; char context[AST_MAX_CONTEXT]; } pickup = { .exten = "", };9. ptrdiff_t: 两个指针相减的结果,long int, stddef.h(cstddef)10. 把不同命令空间里的类作为友类:在各自类的头文件中,对另一个类进行前向声明。 不需要包含对方的头文件(声明了可编译,链接时从动态库以及头文件中去找?)。 如:SessionRecord 的友类是 ConvertToWebm,这样后者就可以访问前者的私有成员。 SessionRecord.h: // the same with COnvertTowebm.h namespace erizo{ class ConvertToWebm; } namespace wiucs{ friend class erizo::ConvertToWebm; class SessionRecord{ } }11. list.assign(3, 7); // 3重复7次赋值 list.assign(listA.begin, listA.end) // 范围赋值12. 类之间的关系: 关联association: A中有B的引用或变量,固定性 泛化generalization: 继承 依赖dependency: 局部变量,方法参数,偶然临时性 聚合agregation: 个体与群体 组合composite: 部件与整体13. 编译64位: 不一定在64位机器上编译; 编译参数加上 -m64 ; 需要安装完整版gcc, sudo apt-get install gcc-multilib14. join() // 主线程等待分支线程结束: branch_thread_.join() 注意控制使得有循环的分支线程可以结束掉
常用函数以及处理
日志: c/C++: log4cxx,这个是Apache的开源,强烈建议C++用户使用,跨平台,支持多线程等优势; 这个容易导致程序崩溃:log4Cplus open VS fopen open: 系统调用,返回文件描述符;设备文件只能用opensaveFd = open("/tmp/CLI_traceRoute.log", O_RDWR | O_CREAT | O_TRUNC, 0766);write...lseek(saveFd, 0, SEEK_SET);ret = read(saveFd, buf, MAXBUF);close(saveFd); open/close, read/write, getc/putc, getchar/putchar 等。 fopen:标准库函数(调用open),返回FILE指针;可移植;用缓存实现FILE *fp = fopen("/proc/net/route", "r");while (fgets(buf, sizeof(buf), fp))fclose(fp); fopen/fclose/freopen, fread/fwrite, fgetc/fputc, fgets/fputs, fseek/ftell/rewind等 写文件后再用rewind()不起作用 // 关闭后,重新打开比较: 输出: fprintf (file或者描述符) vs sprintf(stringBuf),snprintf,vsnprintf(可变长的buf) printf("ID:%x", this); // 打印对象; 后面加fflush(stdout);可提高打印效率 输入: fscan (read from file) 网络字节序转换 uint16_t curSeq = ntohs(rh->seqnum); uint32_t curTs = ntohl(rh->timestamp);修改打印字符串的颜色 // "\033[0;34m" = blue "\033[0m" = none snprintf(buf, size, "\033[0;34m[%d/%02d/%02d %02d:%02d:%02d] %s\033[0m", 1900+tm->tm_year, 1+tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, content);opendir // 目录下的目录流 readdir // 目录的特性 stat(fullName, &dstat) S_ISDIR(dstat.st_mode) closedir(dir); if (access("/cgi-bin/index.cgi"+1, X_OK) == 0) //#include <io h=""> chdir(url + 1) != 0 // change cur process work path //unistd.h if(realpath(purl + 1, realpath_buff) != NULL) // 由相对路径得到绝对路径包裹函数,安全的函数 snprintf(缓存地址,长度,格式,参数1...) fgets(gets) strncpy(strcpy) strncat(strcat)各种字串之间的转换 其他类型(String, Qstring, Cstring)先转换为基本类型char*, 然后再转换 string - char* string str1(str2); // const char* str2 = "char";char* str2 = const_cast<char>(str1.c_str());// string str1 ="string"; QString - char*QString qstr(QString::fromLocal8Bit(str)); // const char* str = "string."; const char* str2 = qstr.toLocal8Bit(); QString - stringQString s2q(const string &s) { return QString(QString::fromLocal8Bit(s.c_str())); } string q2s(const QString &s) { return string((const char *)s.toLocal8Bit()); } CString - char* char *ch = cstr.GetBuffer(cstr.GetLength() + 1); // CString cstr = "cstring."; cstr.ReleaseBuffer(); 系统执行 system(buf); // sprintf(buf,"/etc/network.rc LOAD&");设置非阻塞 fcntl(sockfd ,F_SETFL, O_NONBLOCK); 信号以及闹铃 sigaction(SIGALRM, &sa, NULL); //他是POSIX的信号接口,而signal()是标准C的信号接口 alarm(TIMEOUT) >= 0 // 经过指定秒数后,给当前进程发送 SIGALRM 信号;后一个闹钟将会取消前一个,并从0开始计时,返回前个闹钟剩余的秒数。shutdown(a_c_w, SHUT_WR); //这样关闭套接字更安全比其他方式ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count); 是作用于数据拷贝在两个文件描述符之间的操作函数.这个拷贝操作是内核中操作的,所以称为"零拷贝".//#include <sys h="" sendfile=""> sendfile函数比起read和write函数高效得多,因为read和write是要把数据拷贝到用户应用层操作.url = alloca(strlen(buf) + 12); // alloca 是在栈上分配空间的,尽量不要用。strtok VS strtok_r 分别使用两个 strtok ,会互相干扰(函数中的静态指针,指向下个字串的)pStr = strtok_r(buf, "\n", &outer_ptr);sscanf会从buffer里读进数据,依照argument的设定将数据写回。 sscanf与scanf类似,都是用于输入的,只是后者以键盘(stdin)为输入源,前者以固定字符串为输入源。 count = sscanf(purl, " %[^ ] HTTP/%d.%*d", buf, &blank); 从输入buf以及各式,生成所需字串 sscanf(data,"username=%[^&]&password=%[^&]",username,password);#include <string.h>char *strerror(int errnum);int strerror_r(int errnum, char *buf, size_t n);说明,对于函数strerror_r,第一个参数errnum是错误代码,第二个参数buf是用户提供的存储错误描述的缓存,第三个参数n是缓存的大小。数组char array[10];&array = array // 其值相等,不表示赋值But, (&array + 1) != (array + 1) // 数组名是数组第一个元素的地址,常量不可改变。所以char * p = NULL; // &p为指针变量存放的地址。&array 常量无需存放的地址,表示整个数组的地址func(char ** p); // func(&array); 是错误的,其值等于array, 并没有取得二级地址。指针的指针: 指针的初始值为NULL,把指针的地址记住,分配一段空间后,把分配的空间的地址通过刚才的记住的指针的地址写到指针的值中 指针与引用的比较 int *p; VS int a; int &v = a; //引用必初始化 int *p = &a; VS 引用不能修改函数返回char *如果返回的是栈:野指针,因为函数返回时栈被回收,乱指一气堆:谁释放全局:扩大作用域在函数中定义静态数组: static char value[64]; //如果不是多线程重入,static 也是不错的选择网络通信中的数据传输——————————采用外部表示法网络层中:数据以二进制表示异构机: 指硬件不同,数据表示也不同如A:大端 32位 VS B:小端 16位 // 整数表示C: ASCII VS B: unicode // 字符表示外部表示法: SUN XDR ---> ASN.1 --> XML高位低位的转换写法:低位字 翻到高位字低位字节翻到高位字节比如1030 0f00 写为高位低位: 低位字 翻到高位字 -》0f00 1030, 然后低位字节翻到高位字节-》000f: 3010,完成。然后写成20位地址模式:高位字左移12位,得到 f000:3010字串转化为长整形char buffer[20]="10379cend$3";char *stop;printf("%d\n",strtol(buffer, &stop, 2)); //stop返回非法字符的首地址; 2为转换的2进制printf("%s\n", stop);输出结果:2,379cend$316进制的数字40转换为10进制串char message[3];sprintf(message, "%d", 40); //字串40// 将字串40按照16进制来转化,得到10进制数字long int prelen = strtol(message, NULL, 16); sprintf(message, "%ld", prelen); // print str "64"字串转doublestrtod > Convert string to double atoi > Convert string to int atol > Convert string to long int 字串复制t = strdup(s); // 函数内分配内存free(t); // don't forget!字串比较,忽略大小写strcasecmp在源字串中查找目的字串中任一字符,并返回第一个找时的地址。urlp = strpbrk(iobuf, " \t");result = strpbrk( string, "0123456789" );//在string中找出最先出现0~9中某一个字符的位置字串中查找字符tptr = strchrnul(urlp, ' '); // 未找到,返回串尾script = strchr(script + 1, '/') // 未找到,返回NULLchar * p = strrchr(buf, ' '); // 反向搜索字符小写字符变大写0100 0001 65 41 A0110 0001 97 61 ach = (buf[0] & ~0x20); /* toupper if it's a letter */C 正则表达式函数#include <regex h="">regcomp(结构体指针, 正则表达式,标志);regexec(编译好的结构体, 待查找的字串,找到的个数,找到的结构体数组,标志);打印N个相同的字符,且字符数字为变量fprintf(stderr, "%*c ^\n", iLen, ' ');</regex></sys></char></io>
C++文件包含C的函数
#ifdef __cplusplus extern "C" { #endif ... ... ... #ifdef __cplusplus } #endif
C文件包含C++的函数
1. 将c文件需要的c++函数提取出来,放到另一个单独的c++文件中,2. 并在该文件及其头文件都加extern "C"3. 然后在c文件中include 其头文件即可
头文件
#ifndef __INCfooLibh #define __INCfooLibh #include #define const int // 常量定义块 typedef struct //复合类型定义块 void func(void); //函数原型说明块 #endif /* __INCfooLibh */
数组内元素的个数
#define ARRAY_SIZE(x) ( (unsigned) ( sizeof(x) / sizeof((x)[0]) ) ) // x should be arrayName, not pointer to Array!!!!!!!! int a = sizeof(p) ; // 指针的长度为4 int b = sizeof((p)[0]); // 元素的长度可能为8 所以 numofData = ARRAY_SIZE(p); //0.
定义数组个数
1、#define LISTEN_NUM 10 2、const int LISTEN_NUM = 10; UserProfile users[LISTEN_NUM]; 若用2的方式,运行时才确定,所以用gcc编译会出现Error: variably modified 'users' at file scope 改成1的形式,则没有报错信息。编译时确定。
连接符##和#转字符串
// 因为是C语言宏定义的,所以只在编译时起作用,运行时不行#define A(x) T_##x //字串连接: A(1)------〉T_1#define B(x) #@x //加单引号: B(1)------〉'1'#define C(x) #x //加双引号: C(1)------〉"1"例子1: #define paster(n) printf( "token" #n " = %d\n", token##n ) 那么paster(9)在编译时,上面的这句话被扩展为: printf( "token" "9" " = %d", token9 ); 例子2: #define CLI_RINGTONE_LINE(i) <a>RINGTONE_LINE##i</a> #define _GETSTR(test) #test #define GETSTR(test) _GETSTR(test) printf("%s", GETSTR(CLI_RINGTONE_LINE(2))); // 内外的宏都展开,则 output is “<a>RINGTONE_LINE2“ #define</a> GETSTR(test) #test // 如果没有中间层的宏,则 output is ”CLI_RINGTONE_LINE(2)“
可变参数
// 用可变参数宏(variadic macros)传递可变参数表#define dgbmsg(fmt,...) printf(fmt,__VA_ARGS__) // #define debug(...) printf(__VA_ARGS__)// GCC 宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的","去掉的作用,否则会编译出错#define dbgprint(format,args...) fprintf(stderr, format, ##args) 1) __VA_ARGS__ 只有gcc支持,C++不支持。 // #include <stdarg h=""> 2) __FILE__ 宏在预编译时会替换成当前的源文件名 3) __LINE__ 宏在预编译时会替换成当前的行号 4) __FUNCTION__ 宏在预编译时会替换成当前的函数名称1. 变参的实现#include <stdarg.h> wiCallCtrlSyslog(const char *_format, ...){ va_list ap; // 分配存放变参的内存 char* va_start(ap, _format); // 初始化,确定变参开始位置 rc = vsnprintf(fmt_buf, 255, _format, ap); // vsnprintf函数:格式化字符串复制 va_end(ap); printf("[Call Ctrl] %s", fmt_buf);}2. 例子: 有时,我们想把调试信息输出到屏幕上,而有时则又想把它输出到一个文件中,可参考下面的例子://debug.c#include <stdio h="">#include <string h="">//开启下面的宏表示程序运行在调试版本, 否则为发行版本, 这里假设只有调试版本才输出调试信息#define _DEBUG#ifdef _DEBUG //开启下面的宏就把调试信息输出到文件,注释即输出到终端 #define DEBUG_TO_FILE #ifdef DEBUG_TO_FILE //调试信息输出到以下文件 #define DEBUG_FILE "/tmp/debugmsg" //调试信息的缓冲长度 #define DEBUG_BUFFER_MAX 4096 //将调试信息输出到文件中 #define printDebugMsg(moduleName, format, ...) {\ char buffer[DEBUG_BUFFER_MAX+1]={0};\ snprintf( buffer, DEBUG_BUFFER_MAX \ , "[%s] "format" File:%s, Line:%d\n", moduleName, ##__VA_ARGS__, __FILE__, __LINE__ );\ FILE* fd = fopen(DEBUG_FILE, "a");\ if ( fd != NULL ) {\ fwrite( buffer, strlen(buffer), 1, fd );\ fflush( fd );\ fclose( fd );\ }\ } #else //将调试信息输出到终端 #define printDebugMsg(moduleName, format, ...) \ printf( "[%s] "format" File:%s, Line:%d\n", moduleName, ##__VA_ARGS__, __FILE__, __LINE__ ); #endif //end for #ifdef DEBUG_TO_FILE#else //发行版本,什么也不做 #define printDebugMsg(moduleName, format, ...)#endif //end for #ifdef _DEBUGint main(int argc, char** argv){ int data = 999; printDebugMsg( "TestProgram", "data = %d", data ); return 0;}</string></stdio></stdarg>
守护进程
单独的守护进程:httpd /etc/init.d超级守护进程:多了个一个管理员xinet,并且调用下面的进程时,分为多线程,单线程形式 /etc/xinet.d#include <unistd.h>int daemon(int nochdir, int noclose); //成功返回0,失败返回-1 daemon()函数,主要用于某些程序希望自己脱离终端的控制而运行于后台的情况。 除非nochdir为非零值,如果nochdir为0,那么daemon会从当前目录,更改到根目录(“/”)下运行。 // chdir 除非noclose为非零值,如果noclose为0,那么daemon会将标准输入,标准输出,标准错误输出重定向到/dev/null。 // dup2 父进程自杀,让子进程成为孤儿进程。子进程创建新的会话,并成为该会话的头领进程 // setsid
开发问题
1. buf[10]设置过小,实际可能写入了12个数据,从而导致程序挂掉(退出函数时才出错,可能退出时在回收资源时挂掉)2. 初始化时,正确设置初始值;用完后及时清空问题,确保下次正确执行3. 多线程对共享资源进行抢占,加锁确保共享资源不被破坏。一个线程写,一个线程读,也要加锁;读操作,其本质可能会对资源进行写操作。4. main() 放在namespace里面,就报错:无定义。5. QT4安装所需的库 sudo apt-get install libx11-dev libfreetype6-dev libavahi-gobject-dev libSM-dev libXrender-dev libfontconfig-dev libXext-dev<p>6. 安装指定版本的glibc ./busybox: /lib/libc.so.6: version `GLIBC_2.7' not found (required by ./busybox) 检查当前的版本: ll /lib/libc.so.6 下载: wget http://ftp.gnu.org/pub/gnu/glibc/glibc-2.12.1.tar.gz 配置 # ./glibc-2.12.1/configure --prefix=/usr/local/glibc2.12.1/ --with-headers=/usr/include 编译 # cd glibc-2.7 ; make ; make install 7. 在ubuntu中LD_LIBRARY_PATH不起作用。据说因为安全原因,Linux系统做了限制。8. 注意不同命名空间中,携带空间的名字: erizo::ConvertToWebm 中 wiucs::SessionRecord, 9. 注意 #ifndef XXX_H_,有可能这里的名字写错,造成写了头文件但没有被引用到10. ConvertToWebm c 要消费,SessionRecord s 中生产的 std::list<queue> audio_list_ 错误:c. list = s.list // 仅仅是赋值操作,后续s.list中的变化,不能反映到c.list中 正确:c 中包含s指针,c实际处理的是s的数据: this->ps->list</queue></p>
CLI
CLIisWorkingps |grep debugsh |grep -v grep > /tmp/clips.txtignoreOutputg_saveFd = dup(1);g_newFd = open(fileName, O_RDWR | O_CREAT | O_TRUNC, 0766);dup2(g_newFd, 1)passwordgetchar() and save in the passwd[]termios.h tcgetattr() and err = tcsetattr(fd, TCSAFLUSH, &term); // del or add ECHOFLAGSarraychar tmpbuf[MAXPARAMS][MAXPARAMNAME] = { {0} };strcpy(tmpbuf[argc], temp); // temp is stringcommand treetypedef struct cmd{ char *name;/*命令名称*/ STUHELP help; struct cmd *subCmd;/*子命令集指针*/ funcHandleCmd handleCmd;/*命令执行函数*/ EnCmdMode Auth;} CMD;CMD rootCMD[] = {{"aec",{"Acoustic Echo Cancellation commands\n", "channelid [dev deviceid] {enable | disable | status}"},&nullCMD, Aec, all_mode},};pSubCommand = lookforSubCmd(pCmdName, pNodeCMD, &retChkCmd); // 检查命令if (NULL == pSubCommand) // 没有这个命令 或者 找到两个else if (&nullCMD == pSubCommand) // 找完了OKelse//继续找下一级retChkArg = checkCmdArg(syntaxStr, startIndex, endIndex, argv, &cmdParams); //检查参数retChkGrp = checkGroup(startGrp, &endGrp, &argType, tmpArgStr); //loop {} [] XXretFill = fillBraketParam(tmpArgStr, ¶mNo, pParams, argc, &index, argv); // [{} XXX {} YYY]or retFill = fillParam(¶mNo, pParams, argType, tmpArgStr, argc, &index, argv);readlineinitialize_readline ();rl_bind_key('?', cmd_help);s = rl_copy_text(0, rl_point); // hostname> show ? s = show 得到提示字串后的输入return main(); //Solution the problem that using the "?" and "Tab" can not bind the Enter keyrl_bind_key('\t',cmd_tab_completer);s = rl_copy_text(0, rl_point);//get input_rl_replace_text(line, len, rl_point);rl_insert_text(" ");// while(1)line = readline(prompt); add_history(str);execCmd(str);free(line);recursive readdirvoid getLsStr(char *path, char *lsStr) call itself when stat tells it's S_ISDIR // my firstsomething about CLIgetopt, readline, lex and yacc, flex and bison
线程锁
一个读写锁同时只能有一个写者或多个读者(与CPU数相关)一次只能一个线程拥有互斥锁,其他线程只有等待LINUX多线程互斥量和读写锁区别 boost库中提供了mutex类与lock类,通过组合可以轻易的构建读写锁与互斥锁。 mutex类主要有两种: 独占互斥类: boost::mutex, 有lock和unlock方法, 共享互斥类: boost::shared_mutex, lock/unlock,还有shared_lock/shared_unlock。 lock类独占锁(写锁): boost::unique_lock<t>, T为任意mutex共享锁(读锁): boost::shared_lock<t>中的T只能是shared_mutex类upgrade_lock,它的最大特点就是与shared_lcok不互斥,与别的upgrade_lock和unique_lock互斥。upgrade_lock可以升级为upgrade_to_unique_lock。据boost文档说也可以downgrade成shared_lock boost:mutex:soped_lock // 定义范围内加锁有效注意: 锁时ABC的连环扣,解锁需要按照这个顺序 对队列等的读操作,实际有写得动作,比如修改下标,所以还是要用写锁 从共享的数据,以及参与的线程,来制定锁的方案。</t></t>
算法
排序算法 稳定性:数值相同的两个数,经过排序后,他们之间的相对位置保持不变,称为稳定排序。 内/外排序:待排序的数字都在内存,为内排序;如果部分在内存,排序后调整外存上的数据,为外排序。 时间/空间复杂度:计算复杂程度,存储空间 选择排序:选择最小的放在第一个,剩下的选择最小放第二个位置... 堆排序:建立堆(二叉树),堆顶为最大元素;堆顶与最后一个元素交换,建立堆... 插入排序:一个一个插入到前面有序的数列中 希尔排序:按照增量划分组,组内插入排序,直到增量为1 冒泡排序:相邻两个数比较排序,每轮最大的数沉底 快速排序:一趟扫描,按照基准元素排序,左边的数<基准<右边...
算法
CASE软件(Computer Aided Software Engineering)。 在需求分析阶段,系统分析与设计阶段,系统开发及部署等方面有着强大的支持 交互图(interaction),协作图(communication)和时序图(Timing), 状态图(State),部署图(Deployment),组件图(component),活动图(Activity),
boost
#include <boost hpp="" asio=""> boost::asio::io_service &_ioservice boost::asio::ip::udp::socket* _socket = new udp::socket(_ioservice, udp::endpoint(udp::v4(), port)); boost::asio::ip::udp::endpoint to_point( boost::asio::ip::address::from_string(ip), port); 发送端:socket.send_to(发送到哪里endpoint==ip,port) //async_receive_from异步接收,不阻塞; receive_from没有收到数据时,不能返回 接收端:_socket(用谁接收==port)->async_receive_from()#include <boost hpp="" mutex="" thread=""> boost::mutex _socketMutex; _socketMutex.lock(); _socketMutex.unlock();#include <boost hpp="" array=""> boost::array<char buf_size=""> _recv_buf; boost::asio::buffer(_recv_buf) #include <boost hpp="" bind=""> boost::bind(&boost::asio::io_service::run, &_ioservice)#include <boost hpp="" thread=""> boost::thread _thread; _thread = boost::thread(&ForwardSender::send, this);</boost></boost></char></boost></boost></boost>
<boost hpp="" asio=""><boost hpp="" mutex="" thread=""><boost hpp="" array=""><char buf_size=""><boost hpp="" bind=""><boost hpp="" thread=""></boost></boost></char></boost></boost></boost>
<boost hpp="" asio=""><boost hpp="" mutex="" thread=""><boost hpp="" array=""><char buf_size=""><boost hpp="" bind=""><boost hpp="" thread="">
- gcc -c
- c/c++/gcc
- gcc-4.6.0/gcc/gcc.c#main
- 入口 gcc-4.6.0/gcc/gcc.c
- GCC-C语言编辑器
- gcc -S a.c
- Gcc - c 内存分析
- 了解GCC C++ C
- gcc -c -o
- Gcc - c 内存分析
- linux gcc 编译 c
- gcc -c -o
- GCC -O -C命令
- gcc hello.c -lpthread
- Linux c 开发 - gcc
- gcc编译C语言
- gcc-c-o命令
- gcc & .c | g++ & .cc
- 批量控制工作特征,草图的可见性
- 人在寂寞中
- 世界经典动画短片收集
- Linux Qt 环境以及基础
- secureMRT Linux命令汉字出现乱码
- c/c++/gcc
- NYOJ-78:圈水池
- HTML5 LocalStorage 本地存储
- Lucene Syntax (lucene查询语法详解)
- "完成任务≠结果"心得交流
- UIView的圆角矩形效果 关键是修改layer
- 小米手机与三星S3和摩托罗拉手机系统短信数据库
- linux僵尸进程
- 在windows xp下利用Eclipse--maven构建Mahout