Subject: Re: select call implementation and threads
To: malleswararao venkatanaga <bobbyavn@yahoo.com>
From: Andrey Petrov <petrov@netbsd.org>
List: tech-userlevel
Date: 05/24/2003 17:23:49
On Sat, May 24, 2003 at 04:26:11AM -0700, malleswararao venkatanaga wrote:
> Here is the code i tested with.
> /* Recv.c This is the code that receives messages */
> #include <stdio.h>
> #include<fcntl.h>
> #include<errno.h>
> #include<sys/types.h>
> #include<sys/select.h>
> #include<sys/socket.h>
> #include<netinet/in.h>
> #include <pthread.h>
>
> void * stub_test (void *p );
> pthread_t threads[3];
> int main()
> {
> int rc;
> stub_test2();
> rc = pthread_create(&threads[0], NULL , stub_test
> ,(void *) &threads[0]);
Well, well, well. Try to reverse 2 previous lines.
> if(rc)
> {
> printf("Error in creating thread\n");
> exit(0);
> }
>
> rc = pthread_join( &threads[0], NULL);
> if(rc)
> {
> printf("Error in creating thread\n");
> exit(0);
> }
> }
>
>
> void * stub_test (void *p )
> {
> struct sockaddr_in saddr;
> int sock_fd, i, nread, ndfs, ret_val;
> fd_set read_set;
> char buff[1000];
> struct timeval timeval;
>
> saddr.sin_family = AF_INET;
> saddr.sin_port = 45000;
> saddr.sin_addr.s_addr = htonl ( INADDR_ANY);
> if( (sock_fd = socket( AF_INET , SOCK_DGRAM , 0 ) ) <
> 0 )
> return -1;
>
> if ( bind ( sock_fd , (struct sockaddr * ) &saddr,
> sizeof(saddr ) ) < 0)
> return -1;
>
> ndfs = sock_fd + 1;
> while(1)
> {
> FD_ZERO ( &read_set);
> FD_SET (sock_fd , &read_set);
> ret_val = select(ndfs, &read_set, NULL, NULL,
> NULL);
> if(ret_val >0)
> {
> if(FD_ISSET(sock_fd, &read_set))
> {
>
> nread = recvfrom ( sock_fd , buff , 10, 0
> ,NULL, NULL);
> printf("Read bytes thr 2 %d\n", nread);
> for(i = 0; i <5; i++)
> {
> printf("Buff contents = %c\n", buff[i]);
> }
> }
> }
> else
> {
> printf("\n failed in select");
> }
> }
> return 0;
> }
> void stub_test2()
> {
> struct sockaddr_in saddr2;
> fd_set read_set;
> int sock_fd, ret_val, ndfs;
>
> struct timeval timeval;
>
> timeval.tv_sec = 10;
> timeval.tv_usec = 0;
>
> saddr2.sin_family = AF_INET;
> saddr2.sin_port = 45001;
> saddr2.sin_addr.s_addr = htonl ( INADDR_ANY);
>
> if( (sock_fd = socket( AF_INET , SOCK_DGRAM , 0 ) )
> < 0 )
> return -1;
>
> if ( bind ( sock_fd , (struct sockaddr * ) &saddr2,
> sizeof(saddr2 ) ) < 0)
> return -1;
>
> ndfs = sock_fd + 1;
> while(1)
> {
> FD_ZERO ( &read_set);
> FD_SET (sock_fd , &read_set);
> ret_val = select(ndfs, &read_set, NULL, NULL,NULL
> );
> if(ret_val >0)
> {
> if(FD_ISSET(sock_fd, &read_set))
> {
> int nread;
> char buf[1000];
> printf("\n Recvd some message main thread
> \n");
> nread = read(sock_fd, buf, sizeof(buf));
> if(nread>0)
> {
> printf("\n read %i bytes", nread);
> }
> }
> }
> else
> {
> printf("\n failed in select 1");
> }
> }
>
> }
>
>
> /* The code that sends messages on both the ports */
>
> #include <stdio.h>
> #include <sys/errno.h>
> #include <sys/types.h>
> #include<sys/socket.h>
> #include<sys/select.h>
> #include<netinet/in.h>
>
>
>
> main()
> {
> int sockfd,
> nwritten , i=1;
> const char on = 1;
> struct sockaddr_in saddr;
> unsigned char *pbuf;
>
> pbuf = (unsigned char*)malloc(5);
> strcpy(pbuf, "hello");
>
> saddr.sin_family = AF_INET;
> saddr.sin_addr.s_addr = INADDR_ANY;
>
> if ( ( sockfd = socket ( AF_INET, SOCK_DGRAM,
> 0 ) ) < 0 )
> {
> return -1;
> }
> for ( ; ; )
> {
> if(i==0)
> {
> saddr.sin_port = 45000;
> i = 1;
> }
> else
> {
> {
> saddr.sin_port = 45001;
> i=0;
> }
> nwritten = sendto ( sockfd, pbuf, 5,
> 0,(struct sockaddr *)&saddr,
>
>
> (size_t)(sizeof (struct sockaddr_in)) );
>
> if ( nwritten < 0 )
> {
> return -1;
> }
> printf("\n sent message ");
> sleep(10);
> }
>
> return;
> }
>
>
>
> --- Andrey Petrov <petrov@netbsd.org> wrote:
> > On Fri, May 23, 2003 at 09:50:02AM -0700,
> > malleswararao venkatanaga wrote:
> > > Hi,
> > > I'm facing a problem and it is somewhat like
> > this,
> > > 1)I spawn a thread using pthread_create()
> > > 2) In the thread I open a socket, bind it to a
> > port
> > > say 10001 and block it in the select call for
> > > receiving a UDP message.
> > > Similarly
> > > In my main thread i open a socket and bind it to
> > a
> > > port say 10000 and block the main thread in a
> > select
> > > call.
> > > Both the main thread and the other thread are
> > > essentially waiting for different messages on
> > > different ports and different socket fds with
> > their
> > > respective select calls.
> > > I observe that if i send a messages to both of
> > them
> > > only one of them receives while the other one is
> > still
> > > blocked in the select call though it has messages
> > to
> > > read.
> > >
> >
> > Good thing about userland's threads is that it's
> > easy to debug:
> > build pth library and your applicarion with '-g' and
> > you'll
> > get the full picture of what's going on.
> >
> > The behavouir you described is strange: select is
> > normally
> > redefined to pth_select and that supposed to take
> > care of swiching
> > betwean threads. Well, you can post your application
> > here...
> >
> > Andrey
> >
>
>
> __________________________________
> Do you Yahoo!?
> The New Yahoo! Search - Faster. Easier. Bingo.
> http://search.yahoo.com