socket and pthread

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • AmeL
    New Member
    • Oct 2008
    • 15

    socket and pthread

    Hi all.
    I have a socket. I want to create two threads, one is to read from socket, and another is to write to socket. However, I want these two threads to be able to share the same data, so I created a mutex to lock the resource.
    I don't know what happens with my two threads, but it always quits after it did some tasks.
    Code:
    #include "camel.h"
    #include "irc.h" 
    
    pthread_t         gtid;
    pthread_mutex_t   gMutex;
    
    // The shared resource between reading and writing thread
    char              gSntBuffer[MAX_SIZE_BUFFER];
    
    void*
    SendRequest( INPUT void* pArg)
    {
    	int  lsockfd;
    	DBGSTR(3,
    	       STATUS_SUCCESS,
    		   "FUNCTION ENTRY",
    		   "")
    	lsockfd = (int)pArg;	   
    	while(1)
    	{
    		pthread_mutex_lock(&gMutex);
    	
    		if (gSntBuffer)
    		{
    #ifdef DBG
    			printf("Snt Buffer : %s\n", gSntBuffer);
    #endif
    			write(lsockfd, gSntBuffer, MAX_SIZE_BUFFER);
    		}
    	
    		pthread_mutex_unlock(&gMutex);
    	}
    	DBGSTR(3,
    	       STATUS_SUCCESS,
    		   "FUNCTION EXIT",
    		   "")		
    }
    
    void*
    ReceiveReply( INPUT void* pArg)
    {
    	int   lsockfd = (int)pArg;
    	char  lRcvBuffer[MAX_SIZE_BUFFER];
    	int   lBytes  = 0;
    	DBGSTR(3,
    	       STATUS_SUCCESS,
    		   "FUNCTION ENTRY",
    		   "")	
    	while(1)
    	{
    		lBytes = read(lsockfd, lRcvBuffer, MAX_SIZE_BUFFER);
    #ifdef DBG
    		printf("Rcv Buffer : %s", lRcvBuffer);
    #endif
    		// here I have to filter the lRcvBuffer and 
    		// then write something back to socket by filling 
    		// the gSntBuffer only and let the SendRequest()
    		// do the rest of the job.
    		// 
    		
    		// .... CODE HERE
    	}
    	DBGSTR(3,
    	       STATUS_SUCCESS,
    		   "FUNCTION EXIT",
    		   "")		
    }
    
    tRtnCode
    ConnectIRC( INPUT tProfile profile )
    {
    	int                lsockfd;
    	struct sockaddr_in lservaddr;
    	int                lrvalue;
    
    	pthread_attr_t     lattr;
    
    	DBGSTR(3,
    	       STATUS_SUCCESS,
    		   "FUNCTION ENTRY",
    		   "")		   
    
        memset(&lservaddr, 0, sizeof(lservaddr));
    	lservaddr.sin_family      = AF_INET;
    	lservaddr.sin_port        = htons(profile.port);
    	lservaddr.sin_addr.s_addr = inet_addr(profile.server);
    	
    	if (0 >= (lsockfd = socket(AF_INET, SOCK_STREAM,0)))
    	{
    		DBGINT(1,
    		       ERROR_SOCK_CANNOT_CREATE,
    			   "lsockfd = ",
    			   lsockfd)
    		return (ERROR_SOCK_CANNOT_CREATE);
    	}
    	
    	printf("SendRequest() : losckfd = %d\n", lsockfd);
    	
    	if (0 < (lrvalue = connect(lsockfd, (struct sockaddr*)&lservaddr, sizeof(lservaddr))))
    	{
    		DBGINT(1,
    		       ERROR_SOCK_CANNOT_CONNECT,
    			   "connect() returns ",
    			   lrvalue)
    		return (ERROR_SOCK_CANNOT_CONNECT);
    	}
    	
    	// set attributes
    	pthread_attr_init(&lattr);
    	pthread_attr_setdetachstate(&lattr, PTHREAD_CREATE_DETACHED);
    	pthread_attr_setscope(&lattr, PTHREAD_SCOPE_SYSTEM);
    	
    	// init mutex
    	pthread_mutex_init(gMutex, NULL);
    	pthread_mutex_lock(&gMutex);
    	
    	snprintf(gSntBuffer, 
    	         MAX_SIZE_BUFFER,
    			 IRC_USER,
    			 profile.username,
    			 "",
    			 "",
    			 profile.fullname,
    			 profile.nickname);
    			 
    	pthread_mutex_unlock(&gMutex);
    	
    	// create 2 threads
    	// - read data
    	// - write data
    	
    	pthread_create(&gtid, &lattr, SendRequest,  (void*)lsockfd);
    	pthread_create(&gtid, &lattr, ReceiveReply, (void*)lsockfd);
    	
    	DBGSTR(3,
    	       STATUS_SUCCESS,
    		   "FUNCTION EXIT",
    		   "")
    }
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    It's not in the posted code but you need to ensure that main does not exit (i.e. return) until your threads have finished.

    Comment

    • gpraghuram
      Recognized Expert Top Contributor
      • Mar 2007
      • 1275

      #3
      HI,
      R u creating the thread a sdetached or attached thread?
      If you are creating it as a attcahed thred the call pthread_join() and return after the call.

      Raghu

      Comment

      • AmeL
        New Member
        • Oct 2008
        • 15

        #4
        Thank gpraghuram
        oh yes....you're right. I forget to set the attribute to be JOINABLE, and join them to the main thread, so that the main thread could wait for all of the child threads to be terminated.

        Comment

        • AmeL
          New Member
          • Oct 2008
          • 15

          #5
          Anyway, how about the same resource shared by two threads ?
          I have to use the pthread_mutex_t to lock it right ?
          I am not sure when to lock the resource. Let's say, there are 2 threads, one is to write data, and another is to read data, so in either reading or writing, we lock the resource ? or we lock only when we write ?

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            Lock for both reading and writing but for efficiency keep the lock for as short a time as possible.

            If you don't lock for reading the writing thread may change the data in the middle of you reading it which could produce very strange results.

            Comment

            Working...