1

I am trying this:

#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);
}      

i want to know if this thread will close the file pointer fp automatically or not after exiting.

Darkpingouin
  • 196
  • 12
  • 2
    You can't check in your code, after all, you detached the thread. Assuming your empty loop really keeps the process running, you *can* check from outside, using [`lsof`](https://linux.die.net/man/8/lsof) on linux. –  May 30 '17 at 09:20
  • I referred [this](https://users.cs.cf.ac.uk/Dave.Marshall/C/node30.html#SECTION003040000000000000000) and as per description, it seems that the file is closed in case of a detachable thread. Also, you can use this [link](https://stackoverflow.com/questions/12340695/how-to-check-if-a-given-file-descriptor-stored-in-a-variable-is-still-valid) to check about open file descriptor. – Gaurav Pathak May 30 '17 at 09:25
  • 1
    @GauravPathak Note this says *thread resources* are being released when detached and ended, which is something different than *resources used by the thread*. No, no file descriptors are closed when a thread ends. The file descriptor table is a *shared resource* within a process and a specific fd is **not** owned by a specific thread. – tofro May 30 '17 at 09:59
  • @FelixPalmen `lsof` or similar will only give you the file descriptor. If the code uses a `FILE *` to access the file - as in the example - there's no easy way to recover it, and it may irretrievably leaked. – Andrew Henle May 30 '17 at 10:08
  • Thanks a lot @tofro – Gaurav Pathak May 30 '17 at 12:40

3 Answers3

2

i want to know if this thread will close the file pointer fp automatically or not after exiting.

No, it will not.

If the process exits, the file pointer and the underlying file descriptor/handle will be closed.

Nothing will happen to the actual file pointer and underlying descriptor/handle when a thread exits. The file pointer will remain allocated with all its resources and the underlying descriptor/handle will remain open. If your code does not otherwise track the file pointer, it will be leaked.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • 1
    There's also a common, but very nasty pitfall when a thread inadvertantly closes an *fd* *twice* - This doesn't hurt in a single-threaded environment and will silently be ignored, but with multiple threads the fd could easily have been allocated for another thread between the first and second `close()` – tofro May 30 '17 at 10:54
0

If you don't close it the file descriptor will remain allocated and that will cause a memory leak if your program exits without closing it. You've to explicitly close it with close(fd).Detaching a thread will just let it terminates and releases its own resourses without the need to pthread_join it.

simo-r
  • 733
  • 1
  • 9
  • 13
  • "*the file descriptor will remain allocated and that will cause a memory leak if your program exits without closing it*" well, any recent OS I know about closes file descriptors the moment a process (not thread) ends. So they do not leak then anymore. – alk Jun 03 '17 at 10:12
0

No it will not.

Proof:

#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;

}

Possible output:

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

As you can see, the newly opened fd (3) survives the death of the thread (30702). The detached attribute doesn't play a role here.

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142