Find the answer to your Linux question:
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 12
hi I have a thread function that does that reads the file abc.txt. abc.txt is actually located in a laptop that i have mounted on my linux system. While thread ...
  1. #1
    Just Joined!
    Join Date
    Jul 2008
    Posts
    22

    pthread_cancel not working while thread is blocked in lstat64

    hi

    I have a thread function that does that reads the file abc.txt. abc.txt is actually located in a laptop that i have mounted on my linux system. While thread is reading the file i switched off my laptop.
    Now thread hungs in read call as abc.txt is not available now.

    Also issued the pthread_cancel from the main. But thread actually not got canclled. My program is still hung in thread. Can someone help??

    How can i make pthread_cancel to work even when blocked in reading. I cannot make read operation as non-blocking


    int fd;
    void cleanup(void * context)
    {
    printf("cleanup code\n");
    close(fd);
    }


    void *
    threadfunc2 ()
    {
    int state;
    char * buff;
    int i;
    pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, &state);
    pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &state);
    // pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &state);
    printf ("Thread 2 is going to sleep\n");
    if ((fd = open ("/sideline/fs_655364/files/stp/abc.txt", O_RDONLY )) < 0)
    {
    printf (" rtlinux_mod cannot open fifo \n ");
    }
    else{
    sleep(30);
    for ( i=0; i< 100 ; i++){
    printf("looping i = %d \n",i);
    pthread_cleanup_push( cleanup, NULL );
    read(fd , buff , 100);
    pthread_cleanup_pop(0);
    }
    }

    }


    int
    main ()
    {
    int rc;
    pthread_create (&tid[1], NULL, threadfunc2, NULL);
    sleep (60);
    rc = pthread_cancel (tid[1]);
    printf (" cancel status % d \n ", rc);
    pthread_join (tid[1], NULL);
    printf (" Manin thread exit \n ");
    }

  2. #2
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    It looks to me as though you're doing all the right things, so this is puzzling.

    I do have a question for you, though: why can't you do a non-blocking read?
    --
    Bill

    Old age and treachery will overcome youth and skill.

  3. #3
    Just Joined!
    Join Date
    Jul 2008
    Posts
    22
    Well this just a modified part of big code .
    Actaully the read and open that i have used here will not be exactly like this.
    I have to use all the library operation available with product i am working on
    and they are blocking. I canot change them

  4. #4
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    Two questions for you:
    1. Does the larger code you're working on already use POSIX threads?
    2. What compiler and compiling environment are you using?
    --
    Bill

    Old age and treachery will overcome youth and skill.

  5. #5
    Just Joined!
    Join Date
    Jul 2008
    Posts
    22
    My big code is using POSIX threads.
    But the library operation to read the files/filers are not using pthreds.

    I am using gcc (GCC) 4.1.1 20070105 (Red Hat 4.1.1-52)

    I was wondering if there is some signalling mechanism with help of that i can kill thread. I am not sure if signals will kill the thread or process.

  6. #6
    Just Joined!
    Join Date
    Jul 2008
    Posts
    22
    I digged more and found that thread gets blocked in lstat64 if filer/laptop is disconnected on which lstat64 is operating.

  7. #7
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    I was wondering if there is some signalling mechanism with help of that i can kill thread. I am not sure if signals will kill the thread or process.
    You probably don't want to do that, because you would not be able to do the thread cleanup (releasing mutexes, etc.). In any case, sending a terminating signal will kill the entire process.

    I did some more reading on this situation. Asynchronous cancellation is designed for intense compute loops, not for pulling a thread out of a call to a library function (such as lstat64()) which will not complete. It is possible that, for example, lstat64() is not "async cancellation safe"; that is, there may be overall process resources which might be in an inconsistent state if the function call were terminated and the thread, but not the whole process, were terminated with it.

    So if your thread is hanging in lstat64(), and you can't cancel the thread, the hanging should be considered not a bug, but a feature.

    Try this. Let the thread, in its initialization phase, set up a shared memory segment and an interprocess synchronization mechanism. Then let it fork(). In the child process, all other threads will be effectively dead. The new process should open the "file" and do all the I/O associated with that, communicating with the parent process (actually, the relevant thread in the parent process) via the shared memory segment and the synchronization mechanism.

    The child process should not do any thread-related activity such as dealing with mutexes or condition variables, since these are now unusable and could block (or blow up) the child process.

    Then, instead of canceling the thread, kill the new process.

    For a shared memory segment, don't use the POSIX shared memory facility, because if your whole program blows up, you start accumulating abandoned shared memory segments, and the system allows there to be only a small number of these before it denies requests for a new one. Instead, use mmap() on /dev/zero in the parent process before doing the fork():
    Code:
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <fcntl.h>
    #include <mman.h>
    
    int     fd;
    caddr_t area;
    
    fd=open("/dev/zero",
            O_RDWR
           );
    
    if(fd<0)
    {
      /* error code here */
    }
    
    area=mmap(0,
              desired_segment_size,
              PROT_READ|PROT_WRITE,
              MAP_SHARED,
              fd,
              0
             );
    
    if(area==(caddr_t)-1)
    {
      /* error code here */
    }
    
    close(fd);
    After the fork(), the parent and child can use the pointer area to access the segment of shared memory.

    To synchronize, don't use POSIX semaphores, because if your whole program blows up, you start accumulating abandoned semaphores, and the system allows there to be only a small number of these before it denies requests for a new one. Instead, use advisory locking of some file.

    Of course, after the child process is killed or exits, the parent process (probably the thread which forked the child process) should do a waitpid() to keep zombie processes from accumulating.

    Hope this helps.
    --
    Bill

    Old age and treachery will overcome youth and skill.

  8. #8
    Just Joined!
    Join Date
    Jul 2008
    Posts
    22
    But at same time there will be multiple threads , say we may 1000's of directories on which we need to the lstat64. then how can we make this faster with fork.
    we want 200 threds running parallely so that job is done faster .
    will fork 200 times is good idea??

  9. #9
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    You want this to run as fast as possible, but you also want it to run correctly. "Correctly" means not to hang if the laptop goes away.

    Is forking 200 times a good idea? Possibly, possibly not.

    First, these lstat64() calls are going over a network, yes? If so, the chances are excellent that your network latency is a far greater factor in the overall timing of the application than the fork() overhead is. I have no data to back this up, but it's something to consider.

    If you really want an answer to that question, run a test of both methods. Of course, you shouldn't let the laptop go away during these tests, or the method without fork()s will never complete.

    And as long as you're running tests of lstat64() going over a network, try having only five concurrent threads instead of 200. I'm guessing this will run just about as fast.
    --
    Bill

    Old age and treachery will overcome youth and skill.

  10. #10
    Just Joined!
    Join Date
    Jul 2008
    Posts
    22
    I need some help in case i will opt to use the process rather than threads??

    My orignal problem is . I have process who's task to analyse the files ( do lstat64) on large # of files/dirctories(may be present locally or remotely) after every X mins (say X= 5 min). This information should be collected in less than X mins else it will be meaningless to collect it. so designed whole thing with thread pool (array of pthreds) and work queues ( linked list of work nodes). If any thread is hung ( e.g. filer down) then main will cancel it so that other things can be taken up.

    Now if i cannot use pthreads (because pthread_cancel is blocker for me)and have to opt for process then how can I do the following :


    I want to create the pool of process rather simply forking the 5 processes for 2 reasons
    1) main process can track them ,
    2) avoid creating process again and again as this cycle will be continous. As after every 5 mins main process has to analyse 1000's of files ( that's why i was using threads)

    Also I like to have work queue so that each process from the pool takes up the job and store the result in the shared memeory so that later it can be utilized by the main process all the time.

    How can i create pool of process and create work queue(simply linked list , where each node will contain information of the jobs) that can be shared between process.

    OR

    If there is any better to solve my orignal problem
    Thanks

Page 1 of 2 1 2 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...