2017-05-30 43 views
1

我想这一点:如何检查分离属性的线程是否在退出后释放系统资源?

#include<stdio.h> 
#include<pthread.h> 
void * fun1(void *arg) 
{ 
    FILE *fp; 
    fp=fopen("data","w+"); 
    if(fp==0) 
    { 
    perror("fopen"); 
    return NULL; 
    } 
    perror("fopen"); 
    fprintf(fp,"%s\n","file opened"); 
    return NULL; 
} 


void main() 
{ 
pthread_attr_t atr; 
pthread_attr_init(&atr); 
pthread_attr_setdetachstate(&atr,PTHREAD_CREATE_DETACHED); 

pthread_t thread1; 
pthread_create(&thread1,&atr,&fun1,NULL); 
pthread_attr_destroy(&atr); 
while(1); 
}  

我想知道这是否线程退出后自动或不关闭文件指针fp。

+2

你不能检查你的代码,毕竟你是脱离了线程。假设你的空循环真的让程序继续运行,你可以从外部检查,在linux上使用['lsof'](https://linux.die.net/man/8/lsof)。 –

+0

我提到[this](https://users.cs.cf.ac.uk/Dave.Marshall/C/node30.html#SECTION003040000000000000000),并根据说明,似乎该文件在可拆卸的情况下关闭线。 此外,您可以使用此[链接](https://stackoverflow.com/questions/12340695/how-to-check-if-a-given-file-descriptor-stored-in-a-variable-is-still -valid)来检查打开的文件描述符。 – Gaurav

+1

@GauravPathak请注意,这说*线程资源*在分离和结束时正在释放,这与线程*使用的资源不同。不,没有文件描述符在线程结束时关闭。文件描述符表是进程内的一个*共享资源*,特定的线程拥有特定的fd而不是**。 – tofro

回答

2

我想知道这个线程是否会在退出后自动关闭文件指针fp。

不,它不会。

如果退出进程,文件指针和底层文件描述符/句柄将被关闭。

线程退出时,实际文件指针和底层描述符/句柄不会发生任何变化。文件指针将保持分配其所有资源并且底层描述符/句柄将保持打开状态。如果你的代码没有跟踪文件指针,它将被泄漏。

+1

当线程无意中关闭了* fd * *两次时,还存在一个常见但非常令人讨厌的陷阱* - 这不会在单线程环境中受到伤害,并且会被默默忽略,但是会有多个线程fd很容易被分配给第一个和第二个'close()' – tofro

0

如果不关闭它,文件描述符将保持分配状态,如果程序退出而不关闭则会导致内存泄漏。你必须用close(fd)明确地关闭它。访问一个线程只会让它终止并释放它自己的资源,而不需要它pthread_join它。

+0

“之间的另一个线程”*文件描述符将保持分配状态,如果程序退出而不关闭则会导致内存泄漏*“好吧,任何最近的操作系统在进程(不是线程)结束的时候,我知道关闭文件描述符。所以他们现在不再泄漏。 – alk

0

不,它不会。

证明:

#include<stdio.h> 
#include<semaphore.h> 
#include<pthread.h> 
#include<stdbool.h> 
#include<unistd.h> 

sem_t sem; 

void * fun1(void *arg) 
{ 
    FILE *fp; 
    fp=fopen("data","w+"); 
    if(fp==0) 
    { 
     perror("fopen"); 
     return NULL; 
    } 
    perror("fopen"); 
    fprintf(fp,"%s\n","file opened"); 
    sleep(1); 
    sem_post(&sem); 
    return NULL; 
} 


int main() 
{ 
    pthread_attr_t atr; 
    pthread_attr_init(&atr); 
    pthread_attr_setdetachstate(&atr,PTHREAD_CREATE_DETACHED); 

    sem_init(&sem, 0, 0); 

    long pid = getpid(); 
    char cmd[] = 
     "echo ==================\n" 
     "ls /proc/xxxxxx/fd\n" 
     "ls /proc/xxxxxx/task\n" 
     ; 
    sprintf(cmd, 
     "echo ==================\n" 
     "ls /proc/%ld/fd\n" 
     "ls /proc/%ld/task\n" 
     , pid, pid); 

    system(cmd); 


    pthread_t thread1; 
    pthread_create(&thread1,&atr,&fun1,NULL); 
    system(cmd); 
    pthread_attr_destroy(&atr); 

    sem_wait(&sem); 
    sleep(1); 


    system(
      cmd 
     ); 
    return 0; 

}

可能的输出:

================== 
0 
1 
2 
30697 
================== 
0 
1 
2 
3 
30697 
30702 
================== 
0 
1 
2 
3 
30697 

正如你所看到的,新开的FD(3)生存的线程(30702)的死亡。 detached属性在这里不起作用。