Thread: Terminating secondary thread from another thread

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    3

    Terminating secondary thread from another thread

    Hi everyone, I'm new to this forum. If my qurestion is in wrong place please correct me.
    I'm currently learning about the multithread, and TCP socket. But I was wondering why my code have problem. I search over google still cant fix my problem. Hope anyone can direct me into the right. Thanks

    Basically, this is a TCP client program which do simple msg tranfsfer. When the connection establish, the thread "new_thr" will create another 2 thread which are "send_thr" and "recv_thr". One is to send message to server and another one is to receive message from server. At final, what I want is when either receive or user input an "Q" or "q", the whole process will terminated. So currently I m trying to use thread_cancel to terminate another thread.
    Here is my code


    PHP Code:
    [CODE]/* threadclient.c */
    #include <pthread.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>

    void *cthr_do();
    void *cthr_send();
    void *cthr_recv();


    int main()
    {    
        
    int k;
        
    pthread_t new_thr;
        
    int check pthread_create(&new_thrNULLcthr_doNULL );
        
        
        if(
    check!=0)
        
    printf("The thread cannot be created!");
        
        
    pthread_join (new_thrNULL);
        
        
    printf("The whole process terminated\n");
        return 
    0;
    }

    void *cthr_do()
    {    
        
    printf("thread run sucessful\n");

            
    int sockbytes_receivedconnectedsr;  
            
    char send_data[1024],recv_data[1024];
            
    struct hostent *host;
            
    struct sockaddr_in6 server_addr;  

            
    host gethostbyname("::1");

            if ((
    sock socket(AF_INET6SOCK_STREAM0)) == -1) {
                
    perror("Socket");
                exit(
    1);
            }

            
    server_addr.sin6_family AF_INET6;     
            
    server_addr.sin6_port htons(5000);   
            
    server_addr.sin6_addrin6addr_any/*((struct in_addr *)host->h_addr)*/;
            
    /*bzero(&(server_addr.sin_zero),8);*/
        /*memset(&(server_addr.sin_zero),0,8);*/
            
            
    connected connect(sock, (struct sockaddr *)&server_addrsizeof(server_addr));
             
        if (
    connected== -1
            {
                
    perror("Connect");
                exit(
    1);
            }

        
    printf("The connection is established.\n");    
        
        
    pthread_t send_thrrecv_thr;
                  
                  
    int chk_send pthread_create(&send_thrNULLcthr_send, (void *)sock);
                  if(
    chk_send!=0)
                  
    printf("The send message thread cannot be created!");
                  
                  
    int chk_recv pthread_create(&recv_thrNULLcthr_recv, (void *)sock);              
                  if(
    chk_recv!=0)
                  
    printf("The receive message thread cannot be created!");
                  
                  while (
    1)
                  {
                  
    pthread_join (send_thrNULL);
                  
    pthread_join (recv_thrNULL);
                  
                  if (
    && r)
                  break;
                  }
                  
        
    close(sock);
        
    printf("closed socket\n");              
    }


    void *cthr_send(void *arg)
    {          
              
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLENULL);
              
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUSNULL);
              

              
    char send_data [1024], recv_data[1024]; 
              while (
    1)
              {
                  
    printf("\n SEND (q or Q to quit) : ");
                  
    gets(send_data)/*,1024,stdin)*/;
                  
                  if (
    strcmp(send_data "q") == || strcmp(send_data "Q") == 0)
                  {
                    
    send((int) argsend_data,strlen(send_data), 0);
                    
    /*close ((int) arg);*/
                    
    break;            
                  }
                   
                  else
                     
    send((int) argsend_data,strlen(send_data), 0);
                  }  
                  
                  if ( 
    pthread_cancel(recv_thr) == -
                  {
                  
    perror("pthread_cancel failed");
                  exit(
    3);
                  }  
    //              if (pthread_cancel(recv_thr)!= 0)
    //              perror ("Thread cancelation ");              ;              
    }

    void *cthr_recv(void *arg)
    {
             
                  
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLENULL);
                  
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUSNULL);
                  
                  
    char send_data [1024] , recv_data[1024]; 
                  
    int bytes_received;
                  
                  
                  while (
    1)
                  {
                  
    bytes_received recvfrom((int) argrecv_data1024-10NULLNULL);
                  
    /*recv((int) arg,recv_data,1024,0);*/
                 
                  
    if (bytes_received == -1)
                {
                  
    /*
                   * Socket in error state
                   */
                  
    perror ("Client recv(): ");
                  exit(
    1);
                }        
             
                  
    printf("\nThe number of digit received: %d\n"bytes_received);
                  
    recv_data[bytes_received] = '\0';

                  if (
    strcmp(recv_data"q") == || strcmp(recv_data "Q") == 0)
                  {
                    
    send((int) arg"q"strlen("q"), 0);
    //                close((int) arg);
                    
    break;
                  }

                  else 
                  
    printf("\n RECEIVED DATA = %s \n" recv_data);
                  
    fflush(stdout);
                  }
                  
    //              if (pthread_cancel (send_thr)!= 0)
    //              perror ("Thread cancelation ");              ;              

    }[/CODE
    When i compile this code with the error shown.

    Code:
    shufei@shufei-desktop:~/Desktop$ gcc -lpthread threadclient.c -o threadclient
    threadclient.c: In function ‘cthr_send’:
    threadclient.c:114: error: ‘recv_thr’ undeclared (first use in this function)
    threadclient.c:114: error: (Each undeclared identifier is reported only once
    threadclient.c:114: error: for each function it appears in.)
    is anyone know why it say the recv_thr is undeclare since it was declared in secondary thread. Please forgive my if this is an stupid question.

    Regards,
    wssoh
    Last edited by wssoh85; 12-16-2008 at 08:07 AM. Reason: Explaine about the program

  2. #2
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    The variable recv_thr is declared within the cthr_do function, and is therefore unavailable outside of that function.

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Don't set PTHREAD_CANCEL_ASYNCHRONOUS. The only async-safe functions are pthread_cancel(), pthread_setcancelstate(), and pthread_setcanceltype().

    PTHREAD_CANCEL_ENABLE is the default state, so you shouldn't have to set that either.

    Also keep in mind that gets() isn't guaranteed to be a cancellation point. So you may want to call pthread_testcancel() at the top of the loop.

    http://www.opengroup.org/onlinepubs/...ag_02_09_05_02

    gg

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Why on earth are you using gets() anyway?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Registered User
    Join Date
    Dec 2008
    Posts
    3
    Thank you all for replying. I will try to edit my code.
    Act, because I don't know the default status of pthread_cancel(), therefore, I set the "PTHREAD_CANCEL_ENABLE" just to be make sure that that particular thread can be canceled. Thanks for your remind, codeplug, I'll remove that.

    Erm... May I know what is cancellation point? I use set the "PTHREAD_CANCEL_ASYNCHRONOUS" because I want another thread to be cancel as long as the current thread finish its job. So that the whole process is finich

    My code using gets() because I want to get the input from my keyboard and send to the server. So, I thought is a standard input method. isn't it?

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It's standard, yeah. It's also the most dangerous function in the C standard library. Never, ever use it. Use fgets with stdin instead, like the comment indicates.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    ...And why is this in the C++ section if you are using gets/fgets?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    How to exit a multithreaded program, shutting down all threads:

    Code:
    exit();
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  10. #10
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    exit() is a very dangerous solution, because destructor's of automatic objects are not called, so any kind of object-bound resource is not properly freed.

    1. use cancellation points and call cancel/join from your main thread, or
    2. on threads with endless loop introduce a flag, so the loop is ended if flag is set from main thread. after setting flag call join

  11. #11
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by pheres View Post
    exit() is a very dangerous solution, because destructor's of automatic objects are not called, so any kind of object-bound resource is not properly freed.
    Because cancelling a thread calls destructors?

    (It doesn't.)
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  12. #12
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> threadclient.c
    Destructors?

    But yeah, brewbuck is right. Cancellation cleanup handlers are the only thing you can count on.

    Last sentence of chapter 9 in the PDF I linked above:
    >> Avoid cancellation if at all possible.

    gg

  13. #13
    Registered User
    Join Date
    Dec 2008
    Posts
    3
    Quote Originally Posted by Codeplug View Post
    >> threadclient.c
    Destructors?

    But yeah, brewbuck is right. Cancellation cleanup handlers are the only thing you can count on.

    Last sentence of chapter 9 in the PDF I linked above:
    >> Avoid cancellation if at all possible.

    gg
    The name threadclient is just a name that TCP client with thread. Not a destructor. Sorry for confusing...

  14. #14
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by brewbuck View Post
    Because cancelling a thread calls destructors?
    (It doesn't.)
    But the thread knows when it possibly gets canceled (because it knows in cancellation points) but it doesn't know when it gets killed by exit()?

    But of course I would use the second solution, too.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Thread Prog in C language (seg fault)
    By kumars in forum C Programming
    Replies: 22
    Last Post: 10-09-2008, 01:17 PM
  2. Calling a Thread with a Function Pointer.
    By ScrollMaster in forum Windows Programming
    Replies: 6
    Last Post: 06-10-2006, 08:56 AM
  3. CreateThread ?!
    By Devil Panther in forum Windows Programming
    Replies: 13
    Last Post: 11-15-2005, 10:55 AM
  4. pointer to main thread from worker thread?
    By draegon in forum C++ Programming
    Replies: 2
    Last Post: 10-27-2005, 06:35 AM
  5. Critical Sections, destroying
    By Hunter2 in forum Windows Programming
    Replies: 4
    Last Post: 09-02-2003, 10:36 PM