分类: 嵌入式
2017-02-06 14:53:34
pthread_create (&thread, NULL, &thread_function, NULL);
有三种方法可以避免这种隐蔽的内存泄漏。
(1) 线程创建前,调pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)设置线程分离属性,然后pthread_create ( ptid, &attr, func, NULL )创建。
(2) 线程创建后,调用pthread_detach (pthread_self()),将当前线程与父进程分离。
(3) 在父进程中调用pthread_join()释放子进程资源。
#include
int pthread_join(pthread_t thread, void **value_ptr);
int pthread_detach(pthread_t thread);
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
说明:
1. value_ptr 是指向线程返回值的指针,就是pthread_exit 中的value_ptr 参数,或者是return语句中的返回值, 不能为线程函数的局部变量,否者该指针指向的栈内存不可知, 会有内存错误。
2. 在pthread_join manul 的DESCRIPTION 中,It is unspecified whether a thread that has exited but remains unjoined countsagainst {PTHREAD_THREADS_MAX}. 意思是当一个线程被创建时是可汇合的joinable(默认的attribution), 其他线程或父线程若没有调用pthread_join去做相关资源都被释放(pthread id等),该线程运行结束后资源就得不到释放,所在进程的pthread id数目就可能会累积到达最大数目PTHREAD_THREADS_MAX,此时系统就不能再创建线程了,因为pthread id等资源被用光了,这是在多线程编程中很常见的bug之一。
3. 如果子线程的状态设置为detached,脱离线程却象守护进程:该线程运行结束后会自动释放所有资源,我们不能等待它们终止。显然当我们想让线程自己自动释放所有资源时就用pthread_attr_setdetachstate PTHREAD_CREATE_DETACHED属性
4. FIFO,RR 都是实时调度队列的,实时进程调度队列,是从优先级最高的进程运行,如果当前运行的是FIFO进程,如果他不主动让出cpu,其他进程都不能运行 ,如果是RR(时间片轮转)的,则不会一直独占cpu, 运行一段时间会被切换出来。
创建PTHREAD_CREATE_DETACHED属性线程的范例:
int startThread( pthread_t *ptid, int priority, void* ( *func ) ( void* ), void* data )
{
pthread_t ptid;
pthread_attr_init(&attr);
if ( ( pthread_attr_setschedpolicy ( &attr, SCHED_RR ) != 0 ) )
{
fprintf(stderr, "pthread_attr_setschedpolicy SCHED_RR failed.\n");
return FALSE;
}
if ((pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0 ))
{
fprintf(stderr, "pthread_attr_setdetachstate PTHREAD_CREATE_DETACHED failed.\n");
return FALSE;
}
if ( priority > 0 )
{
struct sched_param sched;
sched.sched_priority = priority;
if ( ( pthread_attr_setschedparam ( &attr, &sched ) != 0 ) )
{
return FALSE;
}
}
//pthread_attr_setXXXX ....
if ( ( pthread_create ( ptid, &attr, func, data ) != 0 )
|| pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)
|| pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) )
{
fprintf(stderr, "pthread_create failed.\n");
return FALSE;
}
pthread_attr_destroy(&attr);
}