linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Problem with pthreads on socket
@ 2004-11-06 10:45 Linux Kernel
  2004-11-06 21:15 ` Jan-Benedict Glaw
  0 siblings, 1 reply; 6+ messages in thread
From: Linux Kernel @ 2004-11-06 10:45 UTC (permalink / raw)
  To: linux-c-programming

Hi to everybody,
I'm not have too much exoerience eith pthread but i
try to use this insted of fork() to have independent
thread processes.
I write a server/client application using socket and
the main problem is that affter first client is
accepted by accept(), the second accepted client broke
the 1-st created thread an the socket remain blocked.
I'm stuck and i don't understand what happening.
A *slice* of my code :
int main()	
	struct sockaddr_in my_addr;    /* my address
information */
        struct sockaddr_in their_addr; /* connector's
address information */
        	
	static int sockfd;
	int th_res=0;
	pthread_t thread;
	pthread_attr_t attr;
	int sin_size,yes=1,new_fd=0;
	char* mPath=NULL;
	MyARGV* marg;
	fd_set fd_read;
	void* mRetTh=NULL;
	int tCount=0,res_lock;
	T_THREAD mThread[10000];
	
		
	mPath=(char*)malloc(256);
	marg=(MyARGV*)malloc(sizeof(MyARGV)+256);	    
	mPath=getenv((const char*)"MY_PATH");	
	
	
	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
            perror("socket");
            exit(1);
        }
	
	if
(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1)
	{
	    perror("SET_SOCK_OPT : \n");
	}
	
        my_addr.sin_family = AF_INET;         /* host
byte order */
        my_addr.sin_port = htons(MYPORT);     /*
short, network byte order */
        my_addr.sin_addr.s_addr = INADDR_ANY; /*
auto-fill with my IP */
        bzero(&(my_addr.sin_zero), 8);        /* zero
the rest of the struct */

        if (bind(sockfd, (struct sockaddr *)&my_addr,
sizeof(struct sockaddr)) \
                                                      
               == -1) {
            perror("bind");
            exit(1);
        }

        if (listen(sockfd, 1) == -1) {
            perror("listen");
            exit(1);
        }
	
		
	FD_ZERO(&fd_read);
	FD_CLR(sockfd,&fd_read);
	FD_SET(sockfd,&fd_read);
	
        while(1) {  /* main accept() loop */
            sin_size = sizeof(struct sockaddr_in);
           
res_lock=select(sockfd+1,&fd_read,NULL,NULL,NULL);
	    
	    if ((new_fd = accept(sockfd, (struct sockaddr
*)&their_addr,&sin_size)) == -1) {
            	perror("accept");
                continue;
            }
            
            marg->s=fcntl(new_fd,F_DUPFD,0);
	    marg->mPath=mPath;
	    marg->their_addr=their_addr;

	    
	    pthread_attr_init(&attr);
	   
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
	   
th_res=pthread_create(&thread,&attr,(void*)MyProcess,(void*)marg);
	    pthread_attr_destroy(&attr);
	    
	    if(th_res==0)
	    {
		tCount++;
		printf("TH COUNT : %d\n",tCount);
		mThread[tCount-1].tIDX=tCount;
		mThread[tCount-1].tID=thread;		
		pthread_join(thread,&mRetTh);
		//close(new_fd); if i close the socket , accept will
create the same hnd_new_sock like previous...bad
ideea.
	    	
	    }
	    else
	    {
	    	perror("CREATE_THREAD");	
	    }
	    
        }
    }

}
void MyProcess(MyARGV* MArg){	
	int maxtry=0,mTime=0;
	int lenrecv=0,lenwrite=0,mCount=1,dCnt=0;
	int MyWait=0;
	char* mBuff=NULL;
	char* realPath=NULL;
	unsigned char *mcmd;
	fd_set fd_read;
	struct timeval tv;
	
	int msize=BUFF_SIZE,t;
	STR_RECV *ss;
	MYSQL *myDATA;
		
		pthread_detach(pthread_self());    
		
		t=setsockopt(MArg->s,SOL_SOCKET,SO_SNDBUF &&
SO_RCVBUF,&msize,sizeof(msize));
		mBuff=(char*)malloc(BUFF_SIZE);
		mcmd=(unsigned char*)malloc(4);	
		    ss=(STR_RECV*)malloc(sizeof(STR_RECV)+1);		
    		    
		    strcpy(ss->mSYS_PATH,MArg->mPath);
		    
		    for(;;)
		    {
			maxtry++;
			if(maxtry==MAX_TRY)
			{
			    exit(0);
			}
			
			    	pthread_mutex_lock(&mmutex);
			   
lenrecv=recv_data(MArg->s,mBuff,mTime,MArg->their_addr,MyWait);
			   	pthread_mutex_unlock(&mmutex);
				
				if(lenrecv>0)
			   	{
			   		
					PutDataInStruct(mBuff,lenrecv,ss);
			   	
			   	
					if(ss->isData==TRUE)
			   		{
						mCount++;
									
						lenwrite=mFile(ss->mfData,realPath,lenrecv-4);
						if(lenwrite>0)                       
						{
				    			
							ss->TYPE_CMD=CLI_CMD_NEXT_PACK;
							ss->USER_CMD=ss->PACKIDX+1;
							myAlignInt(ss->TYPE_CMD,ss->USER_CMD,mcmd);
							pthread_mutex_lock(&mmutex);
							send_cmd(MArg->s,0,mcmd);
							pthread_mutex_unlock(&mmutex);
				    				
						}	
				
		
		    
						//close(new_fd);
		    				//close(recvsock);	
    		    	    		}
					else
			    		{
						myAlignInt(ss->TYPE_CMD,ss->USER_CMD,mcmd);
						pthread_mutex_lock(&mmutex);
						send_cmd(MArg->s,10,mcmd);
						pthread_mutex_unlock(&mmutex);
					}
					memset(mBuff,0x0,BUFF_SIZE);
					memset(mcmd,0x0,4);
					ss->TYPE_CMD=0;
					ss->USER_CMD=0;
					memset(ss->mfData,0x0,lenrecv);
					mTime=0x0;
					lenwrite=0;
				    	maxtry=0;
				}
			   	else
			   	{
					mTime=0;
					
					FD_CLR(MArg->s,&fd_read);
					FD_ZERO(&fd_read);
					FD_SET(MArg->s,&fd_read);
					tv.tv_sec=60;
					tv.tv_usec=0;
					pthread_mutex_lock(&mmutex);
					select(MArg->s+1,&fd_read,NULL,NULL,&tv);
					pthread_mutex_unlock(&mmutex);
				}
			   	
			   	

		    }    

            mBuff=NULL;
	    mcmd=NULL;
	    free(realPath);
	    free(mBuff);
	    
	    close(MArg->s);
	    
	    free(MArg);
	      
	    pthread_exit((void*)1);
	   
}
Thks,

ZaZoo


		
__________________________________ 
Do you Yahoo!? 
Check out the new Yahoo! Front Page. 
www.yahoo.com 
 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Problem with pthreads on socket
  2004-11-06 10:45 Problem with pthreads on socket Linux Kernel
@ 2004-11-06 21:15 ` Jan-Benedict Glaw
  2004-11-07  9:15   ` Linux Kernel
  0 siblings, 1 reply; 6+ messages in thread
From: Jan-Benedict Glaw @ 2004-11-06 21:15 UTC (permalink / raw)
  To: linux-c-programming

[-- Attachment #1: Type: text/plain, Size: 8560 bytes --]

On Sat, 2004-11-06 02:45:41 -0800, Linux Kernel <linuxkrnl@yahoo.com>
wrote in message <20041106104541.53959.qmail@web90004.mail.scd.yahoo.com>:
> int main()	
> 	struct sockaddr_in my_addr;    /* my address
> information */
>         struct sockaddr_in their_addr; /* connector's
> address information */
>         	
> 	static int sockfd;
> 	int th_res=0;
> 	pthread_t thread;
> 	pthread_attr_t attr;
> 	int sin_size,yes=1,new_fd=0;
> 	char* mPath=NULL;
> 	MyARGV* marg;
> 	fd_set fd_read;
> 	void* mRetTh=NULL;
> 	int tCount=0,res_lock;
> 	T_THREAD mThread[10000];
> 	
> 		
> 	mPath=(char*)malloc(256);
> 	marg=(MyARGV*)malloc(sizeof(MyARGV)+256);	    

Why do you allocate a magic number of bytes more than needed? A "MyARGV"
pointer should exactly point to such a struct, not to something that
looks a bit like it :-)

> 	mPath=getenv((const char*)"MY_PATH");	

This is a plain memory leak. Two lines above, you've allocated 256 bytes
(by the way, there's some error checking missing). Here, you throw aray
your pointer to your allocated memory and substitute it for a pointer to
some environment variable. That is, you don't have any chance to ever
free() the first 256 bytes.

> 	
> 	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
> {
>             perror("socket");
>             exit(1);
>         }
> 	
> 	if
> (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1)
> 	{
> 	    perror("SET_SOCK_OPT : \n");
> 	}
> 	
>         my_addr.sin_family = AF_INET;         /* host
> byte order */
>         my_addr.sin_port = htons(MYPORT);     /*
> short, network byte order */
>         my_addr.sin_addr.s_addr = INADDR_ANY; /*
> auto-fill with my IP */
>         bzero(&(my_addr.sin_zero), 8);        /* zero
> the rest of the struct */

Don't ever depend on the order of elements in any structs. Just zero out
the whole struct before you assign any needed values.

>         if (bind(sockfd, (struct sockaddr *)&my_addr,
> sizeof(struct sockaddr)) \
>                                                       
>                == -1) {
>             perror("bind");
>             exit(1);
>         }
> 
>         if (listen(sockfd, 1) == -1) {
>             perror("listen");
>             exit(1);
>         }
> 	
> 		
> 	FD_ZERO(&fd_read);
> 	FD_CLR(sockfd,&fd_read);
> 	FD_SET(sockfd,&fd_read);
> 	
>         while(1) {  /* main accept() loop */
>             sin_size = sizeof(struct sockaddr_in);
>            
> res_lock=select(sockfd+1,&fd_read,NULL,NULL,NULL);

This is another bug. You need to (re-)initialize fd_read each time
before you call select(). By the way -- why do you select() select here
at all? You seem to not use the result afterwards...

> 	    if ((new_fd = accept(sockfd, (struct sockaddr
> *)&their_addr,&sin_size)) == -1) {
>             	perror("accept");
>                 continue;
>             }
>             
>             marg->s=fcntl(new_fd,F_DUPFD,0);
> 	    marg->mPath=mPath;
> 	    marg->their_addr=their_addr;

No need to dup the fd -- just give it to the thread in spe.

> 	    
> 	    pthread_attr_init(&attr);
> 	   
> pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

This can be done easier: just call pthread_create() and pthread_detach()

> th_res=pthread_create(&thread,&attr,(void*)MyProcess,(void*)marg);

You'd have _one_ "thread" per thread, not one for each attempt to create
one! Basic trick: have a struct per client, like this:

struct client {
	struct pthread_t me;
	int fd;
	struct client *next;
};

or something like that. Write two functions (one to alloc such a struct,
fill in "fd", create thread and put it into a linked list of clients;
one to clean-up a client struct) to handle it.

By the way -- if you have a thread function of correct type, you don't
need to cast it!

> 	    pthread_attr_destroy(&attr);

Not for on-stack attr's IIRC.

> 	    if(th_res==0)
> 	    {
> 		tCount++;
> 		printf("TH COUNT : %d\n",tCount);
> 		mThread[tCount-1].tIDX=tCount;
> 		mThread[tCount-1].tID=thread;		

Statically allocated array with no tCound overflow check. Will bomb out
within 0.01sec if correctly hammered!

> 		pthread_join(thread,&mRetTh);

_Either_ detach, or join.

> 		//close(new_fd); if i close the socket , accept will
> create the same hnd_new_sock like previous...bad
> ideea.

Perfectly okay to get the same fd number a second time. If one
connection to a client is closed, the fd may be re-used for the next
client. This is why even an apache running for hundreds of days
typically doesn't exceed 1000 fds ...


> 	    	
> 	    }
> 	    else
> 	    {
> 	    	perror("CREATE_THREAD");	
> 	    }
> 	    
>         }
>     }
> 
> }
> void MyProcess(MyARGV* MArg){	
> 	int maxtry=0,mTime=0;
> 	int lenrecv=0,lenwrite=0,mCount=1,dCnt=0;
> 	int MyWait=0;
> 	char* mBuff=NULL;
> 	char* realPath=NULL;
> 	unsigned char *mcmd;
> 	fd_set fd_read;
> 	struct timeval tv;
> 	
> 	int msize=BUFF_SIZE,t;
> 	STR_RECV *ss;
> 	MYSQL *myDATA;
> 		
> 		pthread_detach(pthread_self());    

Another detach? You already detached this thread in the main()
function...

> 		t=setsockopt(MArg->s,SOL_SOCKET,SO_SNDBUF &&
> SO_RCVBUF,&msize,sizeof(msize));
> 		mBuff=(char*)malloc(BUFF_SIZE);
> 		mcmd=(unsigned char*)malloc(4);	

Magic constants tend to break:-)

> 		    ss=(STR_RECV*)malloc(sizeof(STR_RECV)+1);		

Why this extra byte?

> 		    strcpy(ss->mSYS_PATH,MArg->mPath);

Missing length check

> 		    for(;;)
> 		    {
> 			maxtry++;
> 			if(maxtry==MAX_TRY)
> 			{
> 			    exit(0);

It's a thread -- just kill it.

> 			}
> 			
> 			    	pthread_mutex_lock(&mmutex);

Haven't seen it anywhere. Keep in mind that it needs initialization
prior first use.

> lenrecv=recv_data(MArg->s,mBuff,mTime,MArg->their_addr,MyWait);
> 			   	pthread_mutex_unlock(&mmutex);
> 				
> 				if(lenrecv>0)
> 			   	{
> 			   		
> 					PutDataInStruct(mBuff,lenrecv,ss);
> 			   	
> 			   	
> 					if(ss->isData==TRUE)
> 			   		{
> 						mCount++;
> 									
> 						lenwrite=mFile(ss->mfData,realPath,lenrecv-4);
> 						if(lenwrite>0)                       
> 						{
> 				    			
> 							ss->TYPE_CMD=CLI_CMD_NEXT_PACK;
> 							ss->USER_CMD=ss->PACKIDX+1;
> 							myAlignInt(ss->TYPE_CMD,ss->USER_CMD,mcmd);
> 							pthread_mutex_lock(&mmutex);
> 							send_cmd(MArg->s,0,mcmd);
> 							pthread_mutex_unlock(&mmutex);
> 				    				
> 						}	
> 				
> 		
> 		    
> 						//close(new_fd);
> 		    				//close(recvsock);	

Keep in mind that a network server typically deals with two types of
file descriptors (with regard to it's clients):

- The socket() file descriptor which basically is your start to work as
  a server at all
- The accept() file descriptors -- one for each client, for each
  connection. However, you may get a given number very ofter: they may
  be re-assigned if they were closed before.

>     		    	    		}
> 					else
> 			    		{
> 						myAlignInt(ss->TYPE_CMD,ss->USER_CMD,mcmd);
> 						pthread_mutex_lock(&mmutex);
> 						send_cmd(MArg->s,10,mcmd);
> 						pthread_mutex_unlock(&mmutex);
> 					}
> 					memset(mBuff,0x0,BUFF_SIZE);
> 					memset(mcmd,0x0,4);
> 					ss->TYPE_CMD=0;
> 					ss->USER_CMD=0;
> 					memset(ss->mfData,0x0,lenrecv);
> 					mTime=0x0;
> 					lenwrite=0;
> 				    	maxtry=0;
> 				}
> 			   	else
> 			   	{
> 					mTime=0;
> 					
> 					FD_CLR(MArg->s,&fd_read);
> 					FD_ZERO(&fd_read);
> 					FD_SET(MArg->s,&fd_read);
> 					tv.tv_sec=60;
> 					tv.tv_usec=0;
> 					pthread_mutex_lock(&mmutex);
> 					select(MArg->s+1,&fd_read,NULL,NULL,&tv);
> 					pthread_mutex_unlock(&mmutex);
> 				}
> 			   	
> 			   	
> 
> 		    }    
> 
>             mBuff=NULL;
> 	    mcmd=NULL;
> 	    free(realPath);
> 	    free(mBuff);
> 	    
> 	    close(MArg->s);
> 	    
> 	    free(MArg);
> 	      
> 	    pthread_exit((void*)1);
> 	   
> }

Since I don't know the rest of the application, I don't comment on the
malloc()/free() usage and the locking about resources...

MfG, JBG

-- 
Jan-Benedict Glaw       jbglaw@lug-owl.de    . +49-172-7608481             _ O _
"Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg  _ _ O
 fuer einen Freien Staat voll Freier Bürger" | im Internet! |   im Irak!   O O O
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Problem with pthreads on socket
  2004-11-06 21:15 ` Jan-Benedict Glaw
@ 2004-11-07  9:15   ` Linux Kernel
  2004-11-07 17:05     ` Jan-Benedict Glaw
  0 siblings, 1 reply; 6+ messages in thread
From: Linux Kernel @ 2004-11-07  9:15 UTC (permalink / raw)
  To: Jan-Benedict Glaw, linux-c-programming

Hi,
Thks for your answer,
First of all i must to tell that the code which was
shown by me, was dramatically cut.And i let only what
i consider that is importonat on my problem.
Why i use malloc for any bytes ? Because i'm verry
carefully with all pointers.
Is more practice(at least for me) to use
malloc(fix_size) instead of malloc(size_of_pointer)
because the compiler will consider the maximum size
from memory stack for this pointer. :)
I use MALLOC_CHECK_=1 and i don't have problems with
memory.free() is able to dealocate memory region => 4
bytes.This application , using fork(), consume max.
4-5% from memory with 100 clients on the same time.
Returning on my problem ... :)
is after accept(),accept the second client.
When accept() return the new_fd, the first
thread(which working and do a lot of I/O) is blocked.
I wish to know, like principle, why ?
From what i understand,in fact, this threads are
working asynchronus and by using mutex, to be a switch
between threads.
I wish to know how the threads can run synchronus or
totally independent.
If you know, some how, a sample source code which is
working, please tell me. 
Thks again,
Zazoo
 :)
P.S. I can send by e-mail the entire source code.

--- Jan-Benedict Glaw <jbglaw@lug-owl.de> wrote:

> On Sat, 2004-11-06 02:45:41 -0800, Linux Kernel
> <linuxkrnl@yahoo.com>
> wrote in message
>
<20041106104541.53959.qmail@web90004.mail.scd.yahoo.com>:
> > int main()	
> > 	struct sockaddr_in my_addr;    /* my address
> > information */
> >         struct sockaddr_in their_addr; /*
> connector's
> > address information */
> >         	
> > 	static int sockfd;
> > 	int th_res=0;
> > 	pthread_t thread;
> > 	pthread_attr_t attr;
> > 	int sin_size,yes=1,new_fd=0;
> > 	char* mPath=NULL;
> > 	MyARGV* marg;
> > 	fd_set fd_read;
> > 	void* mRetTh=NULL;
> > 	int tCount=0,res_lock;
> > 	T_THREAD mThread[10000];
> > 	
> > 		
> > 	mPath=(char*)malloc(256);
> > 	marg=(MyARGV*)malloc(sizeof(MyARGV)+256);	    
> 
> Why do you allocate a magic number of bytes more
> than needed? A "MyARGV"
> pointer should exactly point to such a struct, not
> to something that
> looks a bit like it :-)
> 
> > 	mPath=getenv((const char*)"MY_PATH");	
> 
> This is a plain memory leak. Two lines above, you've
> allocated 256 bytes
> (by the way, there's some error checking missing).
> Here, you throw aray
> your pointer to your allocated memory and substitute
> it for a pointer to
> some environment variable. That is, you don't have
> any chance to ever
> free() the first 256 bytes.
> 
> > 	
> > 	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) ==
> -1)
> > {
> >             perror("socket");
> >             exit(1);
> >         }
> > 	
> > 	if
> >
>
(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1)
> > 	{
> > 	    perror("SET_SOCK_OPT : \n");
> > 	}
> > 	
> >         my_addr.sin_family = AF_INET;         /*
> host
> > byte order */
> >         my_addr.sin_port = htons(MYPORT);     /*
> > short, network byte order */
> >         my_addr.sin_addr.s_addr = INADDR_ANY; /*
> > auto-fill with my IP */
> >         bzero(&(my_addr.sin_zero), 8);        /*
> zero
> > the rest of the struct */
> 
> Don't ever depend on the order of elements in any
> structs. Just zero out
> the whole struct before you assign any needed
> values.
> 
> >         if (bind(sockfd, (struct sockaddr
> *)&my_addr,
> > sizeof(struct sockaddr)) \
> >                                                   
>    
> >                == -1) {
> >             perror("bind");
> >             exit(1);
> >         }
> > 
> >         if (listen(sockfd, 1) == -1) {
> >             perror("listen");
> >             exit(1);
> >         }
> > 	
> > 		
> > 	FD_ZERO(&fd_read);
> > 	FD_CLR(sockfd,&fd_read);
> > 	FD_SET(sockfd,&fd_read);
> > 	
> >         while(1) {  /* main accept() loop */
> >             sin_size = sizeof(struct sockaddr_in);
> >            
> > res_lock=select(sockfd+1,&fd_read,NULL,NULL,NULL);
> 
> This is another bug. You need to (re-)initialize
> fd_read each time
> before you call select(). By the way -- why do you
> select() select here
> at all? You seem to not use the result afterwards...
> 
> > 	    if ((new_fd = accept(sockfd, (struct sockaddr
> > *)&their_addr,&sin_size)) == -1) {
> >             	perror("accept");
> >                 continue;
> >             }
> >             
> >             marg->s=fcntl(new_fd,F_DUPFD,0);
> > 	    marg->mPath=mPath;
> > 	    marg->their_addr=their_addr;
> 
> No need to dup the fd -- just give it to the thread
> in spe.
> 
> > 	    
> > 	    pthread_attr_init(&attr);
> > 	   
> >
>
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
> 
> This can be done easier: just call pthread_create()
> and pthread_detach()
> 
> >
>
th_res=pthread_create(&thread,&attr,(void*)MyProcess,(void*)marg);
> 
> You'd have _one_ "thread" per thread, not one for
> each attempt to create
> one! Basic trick: have a struct per client, like
> this:
> 
> struct client {
> 	struct pthread_t me;
> 	int fd;
> 	struct client *next;
> };
> 
> or something like that. Write two functions (one to
> alloc such a struct,
> fill in "fd", create thread and put it into a linked
> list of clients;
> one to clean-up a client struct) to handle it.
> 
> By the way -- if you have a thread function of
> correct type, you don't
> need to cast it!
> 
> > 	    pthread_attr_destroy(&attr);
> 
> Not for on-stack attr's IIRC.
> 
> > 	    if(th_res==0)
> > 	    {
> > 		tCount++;
> > 		printf("TH COUNT : %d\n",tCount);
> > 		mThread[tCount-1].tIDX=tCount;
> > 		mThread[tCount-1].tID=thread;		
> 
> Statically allocated array with no tCound overflow
> check. Will bomb out
> within 0.01sec if correctly hammered!
> 
> > 		pthread_join(thread,&mRetTh);
> 
> _Either_ detach, or join.
> 
> > 		//close(new_fd); if i close the socket , accept
> will
> > create the same hnd_new_sock like previous...bad
> > ideea.
> 
> Perfectly okay to get the same fd number a second
> time. If one
> connection to a client is closed, the fd may be
> re-used for the next
> client. This is why even an apache running for
> hundreds of days
> typically doesn't exceed 1000 fds ...
> 
> 
> > 	    	
> > 	    }
> > 	    else
> > 	    {
> > 	    	perror("CREATE_THREAD");	
> > 	    }
> > 	    
> >         }
> >     }
> > 
> > }
> > void MyProcess(MyARGV* MArg){	
> > 	int maxtry=0,mTime=0;
> > 	int lenrecv=0,lenwrite=0,mCount=1,dCnt=0;
> > 	int MyWait=0;
> 
=== message truncated ===

> ATTACHMENT part 2 application/pgp-signature
name=signature.asc




		
__________________________________ 
Do you Yahoo!? 
Check out the new Yahoo! Front Page. 
www.yahoo.com 
 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Problem with pthreads on socket
@ 2004-11-07 13:09 Ron Michael Khu
  2004-11-07 17:47 ` Linux Kernel
  0 siblings, 1 reply; 6+ messages in thread
From: Ron Michael Khu @ 2004-11-07 13:09 UTC (permalink / raw)
  To: linux prg, Linux Kernel

perhaps  this is  a typical deadlock problem....
where is the mutex variable defined?? r u using or accessing shared 
resources??

Im confused here:
------------------------------------------------------------------               

if(th_res==0)
        {
        tCount++;
        printf("TH COUNT : %d\n",tCount);
        mThread[tCount-1].tIDX=tCount;
        mThread[tCount-1].tID=thread;      
        pthread_join(thread,&mRetTh);
        //close(new_fd); if i close the socket , accept will
create the same hnd_new_sock like previous...bad
ideea.
          
        }
        else
        {  
            perror("CREATE_THREAD");  
        }
--------------------------------------------------------------------------

why does the main thread (the one holding the server socket)
perform a pthread_join() operation whenever it creates a child thread?

I thought ur goal was to create a multi-tasking server... with a server
thread constantly waiting and accepting client connections while leaving 
it to
the client threads to handle the actual client communication?

U see, with ur code, the main/server is actually only capable of 
handling one client at a time...
pthread_join() causes the calling thread(in ur case, the main thread) to 
wait or block until
the child thread terminates(or is cancelled)...

And in case my assumption is wrong(that u want a multitasking server 
app) and if that the
desired behavior is to serve only one client at a time, then what's the 
purpose of spawning
threads? =(

hmmm... i think ur still designing/coding in terms of fork(), where u 
are spawning whole
processes instead of lightweight processes(or threads)



Linux Kernel wrote:

 > Hi to everybody,
 > I'm not have too much exoerience eith pthread but i
 > try to use this insted of fork() to have independent
 > thread processes.
 > I write a server/client application using socket and
 > the main problem is that affter first client is
 > accepted by accept(), the second accepted client broke
 > the 1-st created thread an the socket remain blocked.
 > I'm stuck and i don't understand what happening.
 > A *slice* of my code :
 > int main()  
 >     struct sockaddr_in my_addr;    /* my address
 > information */
 >        struct sockaddr_in their_addr; /* connector's
 > address information */
 >          
 >     static int sockfd;
 >     int th_res=0;
 >     pthread_t thread;
 >     pthread_attr_t attr;
 >     int sin_size,yes=1,new_fd=0;
 >     char* mPath=NULL;
 >     MyARGV* marg;
 >     fd_set fd_read;
 >     void* mRetTh=NULL;
 >     int tCount=0,res_lock;
 >     T_THREAD mThread[10000];
 >    
 >       
 >     mPath=(char*)malloc(256);
 >     marg=(MyARGV*)malloc(sizeof(MyARGV)+256);            
mPath=getenv((const char*)"MY_PATH");  
 >    
 >    
 >     if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
 > {
 >            perror("socket");
 >            exit(1);
 >        }
 >    
 >     if
 > (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1)
 >     {
 >         perror("SET_SOCK_OPT : \n");
 >     }
 >    
 >        my_addr.sin_family = AF_INET;         /* host
 > byte order */
 >        my_addr.sin_port = htons(MYPORT);     /*
 > short, network byte order */
 >        my_addr.sin_addr.s_addr = INADDR_ANY; /*
 > auto-fill with my IP */
 >        bzero(&(my_addr.sin_zero), 8);        /* zero
 > the rest of the struct */
 >
 >        if (bind(sockfd, (struct sockaddr *)&my_addr,
 > sizeof(struct sockaddr)) \
 >                                                                    == 
-1) {
 >            perror("bind");
 >            exit(1);
 >        }
 >
 >        if (listen(sockfd, 1) == -1) {
 >            perror("listen");
 >            exit(1);
 >        }
 >    
 >       
 >     FD_ZERO(&fd_read);
 >     FD_CLR(sockfd,&fd_read);
 >     FD_SET(sockfd,&fd_read);
 >    
 >        while(1) {  /* main accept() loop */
 >            sin_size = sizeof(struct sockaddr_in);
 >           res_lock=select(sockfd+1,&fd_read,NULL,NULL,NULL);
 >                 if ((new_fd = accept(sockfd, (struct sockaddr
 > *)&their_addr,&sin_size)) == -1) {
 >                perror("accept");
 >                continue;
 >            }
 >                       marg->s=fcntl(new_fd,F_DUPFD,0);
 >         marg->mPath=mPath;
 >         marg->their_addr=their_addr;
 >
 >                 pthread_attr_init(&attr);
 >        pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
 >        th_res=pthread_create(&thread,&attr,(void*)MyProcess,(void*)marg);
 >         pthread_attr_destroy(&attr);
 >                 if(th_res==0)
 >         {
 >         tCount++;
 >         printf("TH COUNT : %d\n",tCount);
 >         mThread[tCount-1].tIDX=tCount;
 >         mThread[tCount-1].tID=thread;      
 >         pthread_join(thread,&mRetTh);
 >         //close(new_fd); if i close the socket , accept will
 > create the same hnd_new_sock like previous...bad
 > ideea.
 >           
 >         }
 >         else
 >         {
 >             perror("CREATE_THREAD");  
 >         }
 >                }
 >    }
 >
 > }
 > void MyProcess(MyARGV* MArg){  
 >     int maxtry=0,mTime=0;
 >     int lenrecv=0,lenwrite=0,mCount=1,dCnt=0;
 >     int MyWait=0;
 >     char* mBuff=NULL;
 >     char* realPath=NULL;
 >     unsigned char *mcmd;
 >     fd_set fd_read;
 >     struct timeval tv;
 >    
 >     int msize=BUFF_SIZE,t;
 >     STR_RECV *ss;
 >     MYSQL *myDATA;
 >       
 >         pthread_detach(pthread_self());          
 >         t=setsockopt(MArg->s,SOL_SOCKET,SO_SNDBUF &&
 > SO_RCVBUF,&msize,sizeof(msize));
 >         mBuff=(char*)malloc(BUFF_SIZE);
 >         mcmd=(unsigned char*)malloc(4);  
 >             ss=(STR_RECV*)malloc(sizeof(STR_RECV)+1);      
 >                            strcpy(ss->mSYS_PATH,MArg->mPath);
 >                         for(;;)
 >             {
 >             maxtry++;
 >             if(maxtry==MAX_TRY)
 >             {
 >                 exit(0);
 >             }
 >           
 >                     pthread_mutex_lock(&mmutex);
 >                
lenrecv=recv_data(MArg->s,mBuff,mTime,MArg->their_addr,MyWait);
 >                    pthread_mutex_unlock(&mmutex);
 >               
 >                 if(lenrecv>0)
 >                    {
 >                      
 >                     PutDataInStruct(mBuff,lenrecv,ss);
 >                  
 >                  
 >                     if(ss->isData==TRUE)
 >                        {
 >                         mCount++;
 >                                   
 >                         lenwrite=mFile(ss->mfData,realPath,lenrecv-4);
 >                         
if(lenwrite>0)                                               {
 >                               
 >                             ss->TYPE_CMD=CLI_CMD_NEXT_PACK;
 >                             ss->USER_CMD=ss->PACKIDX+1;
 >                             myAlignInt(ss->TYPE_CMD,ss->USER_CMD,mcmd);
 >                             pthread_mutex_lock(&mmutex);
 >                             send_cmd(MArg->s,0,mcmd);
 >                             pthread_mutex_unlock(&mmutex);
 >                                   
 >                         }  
 >               
 >       
 >                                     //close(new_fd);
 >                             //close(recvsock);  
 >                                }
 >                     else
 >                         {
 >                         myAlignInt(ss->TYPE_CMD,ss->USER_CMD,mcmd);
 >                         pthread_mutex_lock(&mmutex);
 >                         send_cmd(MArg->s,10,mcmd);
 >                         pthread_mutex_unlock(&mmutex);
 >                     }
 >                     memset(mBuff,0x0,BUFF_SIZE);
 >                     memset(mcmd,0x0,4);
 >                     ss->TYPE_CMD=0;
 >                     ss->USER_CMD=0;
 >                     memset(ss->mfData,0x0,lenrecv);
 >                     mTime=0x0;
 >                     lenwrite=0;
 >                         maxtry=0;
 >                 }
 >                    else
 >                    {
 >                     mTime=0;
 >                   
 >                     FD_CLR(MArg->s,&fd_read);
 >                     FD_ZERO(&fd_read);
 >                     FD_SET(MArg->s,&fd_read);
 >                     tv.tv_sec=60;
 >                     tv.tv_usec=0;
 >                     pthread_mutex_lock(&mmutex);
 >                     select(MArg->s+1,&fd_read,NULL,NULL,&tv);
 >                     pthread_mutex_unlock(&mmutex);
 >                 }
 >                  
 >                  
 >
 >             }  
 >            mBuff=NULL;
 >         mcmd=NULL;
 >         free(realPath);
 >         free(mBuff);
 >                 close(MArg->s);
 >                 free(MArg);
 >                   pthread_exit((void*)1);
 >        }
 > Thks,
 >
 > ZaZoo
 >
 >
 >       
 > __________________________________ Do you Yahoo!? Check out the new 
Yahoo! Front Page. www.yahoo.com
 >
 > -
 > To unsubscribe from this list: send the line "unsubscribe 
linux-c-programming" in
 > the body of a message to majordomo@vger.kernel.org
 > More majordomo info at  http://vger.kernel.org/majordomo-info.html
 >
 >
 > 
 >




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Problem with pthreads on socket
  2004-11-07  9:15   ` Linux Kernel
@ 2004-11-07 17:05     ` Jan-Benedict Glaw
  0 siblings, 0 replies; 6+ messages in thread
From: Jan-Benedict Glaw @ 2004-11-07 17:05 UTC (permalink / raw)
  To: linux-c-programming

[-- Attachment #1: Type: text/plain, Size: 1656 bytes --]

On Sun, 2004-11-07 01:15:17 -0800, Linux Kernel <linuxkrnl@yahoo.com>
wrote in message <20041107091517.63691.qmail@web90004.mail.scd.yahoo.com>:
> >From what i understand,in fact, this threads are
> working asynchronus and by using mutex, to be a switch
> between threads.

Correct is that they're asynchronous to each other. But mutexes aren't
used to switch between them. Mutexes are used to lock-out any other
thready while accessing commonly-used resources.

For example, if you have an application that echoes everything back, you
probably don't need *any* mutexes at all, because receiving one byte and
sending it back doesn't access any commonly used resources.

> I wish to know how the threads can run synchronus or
> totally independent.

They are independant. If you need "synchronous" working mode, you
probably shouldn't use threads at all:-)

> If you know, some how, a sample source code which is
> working, please tell me. 

> P.S. I can send by e-mail the entire source code.

Maybe first start with an exact description of what needs to be done. To
speak honest (and not offending), parts of your sources looked quite
spaghetti-like (but that may be because of cutting out any unneeded
code). So maybe a description of the exact task would be a better start
here...

MfG, JBG

-- 
Jan-Benedict Glaw       jbglaw@lug-owl.de    . +49-172-7608481             _ O _
"Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg  _ _ O
 fuer einen Freien Staat voll Freier Bürger" | im Internet! |   im Irak!   O O O
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Problem with pthreads on socket
  2004-11-07 13:09 Ron Michael Khu
@ 2004-11-07 17:47 ` Linux Kernel
  0 siblings, 0 replies; 6+ messages in thread
From: Linux Kernel @ 2004-11-07 17:47 UTC (permalink / raw)
  To: Ron Michael Khu, linux prg

Hi,
Thks for you answer. :)
For sure you are right.The problem is in my mind.
I thinking like if i using fork().
The mutex variable is initialized with
PTHREAD_MUTEX_INITIALIZER.But is a global one and for
this reason is not showed in the code.
I will not use pthread_join() and i will try to
intialize a memory to be shared between threads.
Thks 
 :)
Zazoo

--- Ron Michael Khu <ronkhu@ntsp.nec.co.jp> wrote:

> perhaps  this is  a typical deadlock problem....
> where is the mutex variable defined?? r u using or
> accessing shared 
> resources??
> 
> Im confused here:
>
------------------------------------------------------------------
>               
> 
> if(th_res==0)
>         {
>         tCount++;
>         printf("TH COUNT : %d\n",tCount);
>         mThread[tCount-1].tIDX=tCount;
>         mThread[tCount-1].tID=thread;      
>         pthread_join(thread,&mRetTh);
>         //close(new_fd); if i close the socket ,
> accept will
> create the same hnd_new_sock like previous...bad
> ideea.
>           
>         }
>         else
>         {  
>             perror("CREATE_THREAD");  
>         }
>
--------------------------------------------------------------------------
> 
> why does the main thread (the one holding the server
> socket)
> perform a pthread_join() operation whenever it
> creates a child thread?
> 
> I thought ur goal was to create a multi-tasking
> server... with a server
> thread constantly waiting and accepting client
> connections while leaving 
> it to
> the client threads to handle the actual client
> communication?
> 
> U see, with ur code, the main/server is actually
> only capable of 
> handling one client at a time...
> pthread_join() causes the calling thread(in ur case,
> the main thread) to 
> wait or block until
> the child thread terminates(or is cancelled)...
> 
> And in case my assumption is wrong(that u want a
> multitasking server 
> app) and if that the
> desired behavior is to serve only one client at a
> time, then what's the 
> purpose of spawning
> threads? =(
> 
> hmmm... i think ur still designing/coding in terms
> of fork(), where u 
> are spawning whole
> processes instead of lightweight processes(or
> threads)
> 
> 
> 
> Linux Kernel wrote:
> 
>  > Hi to everybody,
>  > I'm not have too much exoerience eith pthread but
> i
>  > try to use this insted of fork() to have
> independent
>  > thread processes.
>  > I write a server/client application using socket
> and
>  > the main problem is that affter first client is
>  > accepted by accept(), the second accepted client
> broke
>  > the 1-st created thread an the socket remain
> blocked.
>  > I'm stuck and i don't understand what happening.
>  > A *slice* of my code :
>  > int main()  
>  >     struct sockaddr_in my_addr;    /* my address
>  > information */
>  >        struct sockaddr_in their_addr; /*
> connector's
>  > address information */
>  >          
>  >     static int sockfd;
>  >     int th_res=0;
>  >     pthread_t thread;
>  >     pthread_attr_t attr;
>  >     int sin_size,yes=1,new_fd=0;
>  >     char* mPath=NULL;
>  >     MyARGV* marg;
>  >     fd_set fd_read;
>  >     void* mRetTh=NULL;
>  >     int tCount=0,res_lock;
>  >     T_THREAD mThread[10000];
>  >    
>  >       
>  >     mPath=(char*)malloc(256);
>  >     marg=(MyARGV*)malloc(sizeof(MyARGV)+256);    
>        
> mPath=getenv((const char*)"MY_PATH");  
>  >    
>  >    
>  >     if ((sockfd = socket(AF_INET, SOCK_STREAM,
> 0)) == -1)
>  > {
>  >            perror("socket");
>  >            exit(1);
>  >        }
>  >    
>  >     if
>  >
>
(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1)
>  >     {
>  >         perror("SET_SOCK_OPT : \n");
>  >     }
>  >    
>  >        my_addr.sin_family = AF_INET;         /*
> host
>  > byte order */
>  >        my_addr.sin_port = htons(MYPORT);     /*
>  > short, network byte order */
>  >        my_addr.sin_addr.s_addr = INADDR_ANY; /*
>  > auto-fill with my IP */
>  >        bzero(&(my_addr.sin_zero), 8);        /*
> zero
>  > the rest of the struct */
>  >
>  >        if (bind(sockfd, (struct sockaddr
> *)&my_addr,
>  > sizeof(struct sockaddr)) \
>  >                                                  
>                  == 
> -1) {
>  >            perror("bind");
>  >            exit(1);
>  >        }
>  >
>  >        if (listen(sockfd, 1) == -1) {
>  >            perror("listen");
>  >            exit(1);
>  >        }
>  >    
>  >       
>  >     FD_ZERO(&fd_read);
>  >     FD_CLR(sockfd,&fd_read);
>  >     FD_SET(sockfd,&fd_read);
>  >    
>  >        while(1) {  /* main accept() loop */
>  >            sin_size = sizeof(struct sockaddr_in);
>  >          
> res_lock=select(sockfd+1,&fd_read,NULL,NULL,NULL);
>  >                 if ((new_fd = accept(sockfd,
> (struct sockaddr
>  > *)&their_addr,&sin_size)) == -1) {
>  >                perror("accept");
>  >                continue;
>  >            }
>  >                      
> marg->s=fcntl(new_fd,F_DUPFD,0);
>  >         marg->mPath=mPath;
>  >         marg->their_addr=their_addr;
>  >
>  >                 pthread_attr_init(&attr);
>  >       
>
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
>  >       
>
th_res=pthread_create(&thread,&attr,(void*)MyProcess,(void*)marg);
>  >         pthread_attr_destroy(&attr);
>  >                 if(th_res==0)
>  >         {
>  >         tCount++;
>  >         printf("TH COUNT : %d\n",tCount);
>  >         mThread[tCount-1].tIDX=tCount;
>  >         mThread[tCount-1].tID=thread;      
>  >         pthread_join(thread,&mRetTh);
>  >         //close(new_fd); if i close the socket ,
> accept will
>  > create the same hnd_new_sock like previous...bad
>  > ideea.
>  >           
>  >         }
>  >         else
>  >         {
>  >             perror("CREATE_THREAD");  
>  >         }
>  >                }
>  >    }
>  >
>  > }
>  > void MyProcess(MyARGV* MArg){  
>  >     int maxtry=0,mTime=0;
>  >     int lenrecv=0,lenwrite=0,mCount=1,dCnt=0;
>  >     int MyWait=0;
>  >     char* mBuff=NULL;
>  >     char* realPath=NULL;
> 
=== message truncated ===



		
__________________________________ 
Do you Yahoo!? 
Check out the new Yahoo! Front Page. 
www.yahoo.com 
 


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2004-11-07 17:47 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-11-06 10:45 Problem with pthreads on socket Linux Kernel
2004-11-06 21:15 ` Jan-Benedict Glaw
2004-11-07  9:15   ` Linux Kernel
2004-11-07 17:05     ` Jan-Benedict Glaw
  -- strict thread matches above, loose matches on Subject: below --
2004-11-07 13:09 Ron Michael Khu
2004-11-07 17:47 ` Linux Kernel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).