1.提高程序运行效率
将大量的内存开销的操作,放在判断之后
2.共享内存环形队列,判断空\满\size
3.gettimeofday
#include <assert.h>
#include <sys/time.h>
int main()
{
float time_use=0;
struct timeval start;
struct timeval end;
gettimeofday(&start,NULL);
fun();
time_use=(end.tv_sec-start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);//微秒
}
#define SECOND_MASK 1000000000LL
static uint64_t get_clock_ns ()
{
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) < 0) {
logger ("clock_gettime err: %s", strerror(errno));
return 0;
}
return ts.tv_sec * SECOND_MASK + ts.tv_nsec; // tv_sec 秒 tv_nsec 纳秒
}
4.宏发生错误,使用goto语句
#define GF_OPTION_INIT(xxx, xxx, err_label) \
do{ \
int ret = 0; \
ret = func(); \
if(ret == -1) \
goto err_label; \
} while(0)
补充:宏定义中,\ 后面一定不要加空格,会报warning
5.缓冲区溢出(str函数API)
禁止使用strcpy、strcat、sprintf等危险函数
使用strncpy、strncat、snprintf等函数时,n为缓冲区可接收的最大长度减一,而不是要拷贝长度
char buf[TMP_BUF_SIZE];
snprintf(buf, TMP_BUF_SIZE - 1, "/proc/%d/cmdline", pid); // n为缓冲区可接收长度-1
char proc_name[TMP_BUF_SIZE];
strncpy(proc_name, &buf[i + 1], TMP_BUF_SIZE - 1); // // n为缓冲区可接收长度-1
proc_name[TMP_BUF_SIZE - 1] = '\0';
6.string字符串转number
不使用atoi, atol读取数字,除非对输入合法性没有要求的场合。
通常情况下:
int–>strtol
unsigned int --> strtoul
浮点数 --> strtod
有符号的64位整数 --> strtoll
无符号的64位整数 --> strtoull
strtol long int
strtoll long long int
strtoul unsigned long int
strtoull unsigned long long int
atoi 转化为int
atof 转化为float
atol 传化为long int, 等价于 strtol(nptr, (char**) NULL, 0);
atoll 转化为long long int, 等价于 strtoll(nptr, (char**) NULL, 0);
7.结构体(初始化)
// 定义函数指针类型
typedef int(*pFUNC)(int, int);
// 结构体类型的声明
struct stu{
int age;
int sno;
pFUNC func_cbk; // 函数指针成员
};
int do_cbk(int age, int sno) {
printf("age = %d, sno = %d\n", age, sno);
}
// 定义结构体类型的变量,并对成员初始化
struct stu = student {
.age = 25, // 注意:后面是逗号,不是分号
.sno = 89757,
func_cbk = do_cbk,
};
- 进程名、进程号
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#define TMP_BUF_SIZE 1024
/**
* 根据pid获得进程名(不支持带空格冒号的名字)
* 参数:
* pid [IN]: 进程pid
* proc_name [OUT]: 进程名
* 返回值:
*/
void
get_name_by_pid(pid_t pid, char *proc_name)
{
char buf[TMP_BUF_SIZE];
snprintf(buf, TMP_BUF_SIZE, "/proc/%d/cmdline", pid);
FILE* fp = fopen(buf, "r");
if(fp == NULL){
return;
}
memset(buf, 0, TMP_BUF_SIZE);
(void)fread(buf, 1, TMP_BUF_SIZE - 1, fp);
fclose(fp);
/* 去空格等干扰字符 */
size_t tmp_len = strlen(buf);
int i = 0;
for (; i <= tmp_len; ++i){
if (buf[i] == ' ' || buf[i] == ':'){
buf[i] = '\0';
break;
}
}
tmp_len = strlen(buf);
i = tmp_len;
/* 提取进程名 */
for (; i >= 0; --i){
if (buf[i] == '/'){
break;
}
}
strncpy(proc_name, &buf[i + 1], TMP_BUF_SIZE - 1);
proc_name[TMP_BUF_SIZE - 1] = '\0';
}
/**
* 通过进程ID,得到进程名
* @param [in] pid 进程ID
* @param [out] name 进程名
* @param [in] size 保存name的数组的长度
* @return 成功,0;失败,-1
*/
int get_process_name(const char *pid, char *name, size_t size)
{
char buf[128];
int fd = -1;
ssize_t ret = 0;
snprintf(buf, sizeof(buf)-1, "/proc/%s/process_name", pid);
fd = open(buf, O_RDONLY);
if ( fd < 0 )
return -1;
do{
ret = read(fd, name, size);
if ( ret < 0 && EINTR == errno )
continue;
break;
}while(1);
close(fd);
/* 去掉换行符 */
if ( ret > 0 )
name[ret - 1] = '\0';
return ret > 0 ? 0 : -1;
}
int main()
{
// 1. 进程名-->进程ID
char proc_name[1024];
get_name_by_pid(getpid(), proc_name);
printf("%s\n", proc_name);
// 2. 进程ID-->进程名
int ret;
char pid[64];
char *ptr = NULL;
char process_name[64];
sprintf(pid,"%d",getpid());
/* 解析进程名 */
ret = get_process_name(pid, process_name, sizeof(process_name) - 1);
if ( ret < 0 )
return -1;
printf("process_name = %s\n", process_name);
return 0;
}