嵌入式之去模块初始化
初始化和去初始化一般是成对出现的,而很多时候,往往会忽略去初始化过程,因为部分的情况下,进程一结束,资源就会被系统自动回收,也就没有去初始化的必要,这个很容易养成忽略去初始化的过程,系统资源管理考虑不全的习惯。当分配堆内存时,申请共享内存、申请锁资源等系统资源时,如果在进程退出后,不做销毁、释放,就会占用系统的资源,影响资源的配置、进程的正常运行。所以不管什么时候,都应该养成去初始化的习惯。
去初始化只要考虑一下以下方面:
(1)内存释放
(2)线程释放
(3)系统资源销毁(共享内存、锁资源、信号量等)
(4)释放描述符(tcp通信描述符、文件描述符等)
…
内存释放
内存释放需要注意几个细节
(1)避免野指针
内存释放后,需要将指针置为NULL
free(p);
p=NULL;
(2)内存释放的先后顺序问题
struct str
{
int age;
char *name;
}*str_manage;
str_manage = (struct str *)malloc(sizeof(*str_manage));
如果先free(str_manage);后free(name);则是由问题的
因为free(str_manage),结构体内的name变量占用的空间被释放了,此时的释放name就会出错。
正确的做法是先释放结构体成员free(name),后释放结构体(str_manage)
线程释放
通常会建立一个全局变量来控制线程开启与关闭,初始化时就将变量置为1,去初始化时就将变量置为0。
例如:变量Quit来控制线程的开关,去初始化时只需将Quit变为0即可实现线程的退出。线程退出后需要对资源进行销毁。
int Thread_fun()
{
while(Quit)
{
}
return 0;
}
Linux系统中程序的线程资源是有限的,表现为对于一个程序其能同时运行的线程数是有限的。而默认的条件下,一个线程结束后,其对应的资源不会被释放,于是,如果在一个程序中,反复建立线程,而线程又默认的退出,则最终线程资源耗尽,进程将不再能建立新的线程。
线程释放分为可结合的(joinable)和 分离的(detached)两种,线程默认是可结合的。可结合的线程在线程退出后不会立即释放资源,必须要调用pthread_join来显式的结束线程。分离的线程在线程退出时系统会自动回收资源。
(1)分离线程
在线程中调用pthread_detach(pthread_self());
注:设置为分离的线程是不能调用pthread_join的,调用后会出错
(2)可结合线程
使用pthread_join回收线程。三种线程退出方式可用pthread_join回收
1、子线程使用return退出,主线程中使用pthread_join回收线程。
2、子线程使用pthread_exit退出,主线程中使用pthread_join接收pthread_exit的返回值,并回收线程。
3、主线程中调用pthread_cancel,然后调用pthread_join回收线程。
void pthread_exit(void *retval);
参数:retval表示线程退出状态,通常传NULL
int pthread_join(pthread_t thread,void **rval_ptr);
//成功返回0,否则返回错误编号
int pthread_cancel(pthread_t tid);
//成功返回0,失败返回错误编号
注:分离线程的资源可以自动回收,但无法确定线程资源是什么时候回收的,可结合线程是人为自动回收,可以确定线程资源是什么时候回收的。
系统资源销毁
(1)互斥锁
pthread_mutex_destroy(&AudioAlarmCtrl.AudioAlarm_mutex);
释放描述符
close(fp);