红联Linux门户
Linux帮助

静态变量的用处:文件句柄的妥善放置

发布时间:2016-07-30 15:14:19来源:linux网站作者:六个九十度
最近做的一个任务,是在一个线程中不断接收UDP包,并将包dump到文件内。
 
代码这么写:
#include <stdio.h>  
#include <unistd.h>  
#include <sys/syscall.h>//Linux system call for thread id  
#include <assert.h>  
#include <pthread.h>  
void logMsg()  
{  
int loop = 0;  
FILE *fp = fopen("/tmp/mo_send.txt", "w");  
if (loop < 100)  
fprintf(fp, "%d\n", loop);  
else if (100 == loop)  
fclose(fp);  
loop++;  
}  
void *nbi(void *arg)  
{  
printf("child thread lwpid = %u\n", syscall(SYS_gettid));  
while (1)  
{  
logMsg();  
usleep(50*1000);  
}  
}  
int main()  
{  
pthread_t tid;  
int rc;  
printf("main thread lwpid = %u\n", syscall(SYS_gettid));  
rc = pthread_create(&tid, NULL, nbi, NULL);  
assert(0 == rc);  
pthread_join(tid, NULL); 
return 0;  
}
 
运行完毕后,查看log文件,空文件!
思索良久后才发现是一个低级错误:C局部变量每次都初始化,导致文件重复打开,并将上次写入的内容冲走,但是文件句柄放到函数外部也不好,怕污染名称空间,于是想到了static修饰符。
 
直接给loop和fp前面加static会报错:
f_test.c: In function 'logMsg':
f_test.c:9:2: error: initializer element is not constant
static FILE *fp = fopen("/tmp/mo_send.txt", "w");
^
 
原来静态变量本质上跟全局变量一样,只能用常量来初始化,只是编译器在限制了其scope而已。
 
再改代码:
#include <stdio.h>  
#include <unistd.h>  
#include <sys/syscall.h>//Linux system call for thread id  
#include <assert.h>  
#include <pthread.h>  
void logMsg()  
{  
static int loop = 0;  
static FILE *fp = NULL;  
if (NULL == fp)  
fp = fopen("/tmp/mo_send.txt", "w");  
if (loop < 100)  
fprintf(fp, "%d\n", loop);  
else if (100 == loop)  
fclose(fp);  
loop++;  
}  
void *nbi(void *arg)  
{  
printf("child thread lwpid = %u\n", syscall(SYS_gettid));  
while (1)  
{  
logMsg();  
usleep(50*1000);  
}  
}  
int main()  
{  
pthread_t tid;  
int rc;  
printf("main thread lwpid = %u\n", syscall(SYS_gettid));  
rc = pthread_create(&tid, NULL, nbi, NULL);  
assert(0 == rc);  
pthread_join(tid, NULL);
return 0;  
}
 
再运行就log文件就正常了。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/22860.html