From: Linux Kernel <linuxkrnl@yahoo.com>
To: Jan-Benedict Glaw <jbglaw@lug-owl.de>,
linux-c-programming@vger.kernel.org
Subject: Re: Problem with pthreads on socket
Date: Sun, 7 Nov 2004 01:15:17 -0800 (PST) [thread overview]
Message-ID: <20041107091517.63691.qmail@web90004.mail.scd.yahoo.com> (raw)
In-Reply-To: <20041106211522.GJ2094@lug-owl.de>
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
next prev parent reply other threads:[~2004-11-07 9:15 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20041107091517.63691.qmail@web90004.mail.scd.yahoo.com \
--to=linuxkrnl@yahoo.com \
--cc=jbglaw@lug-owl.de \
--cc=linux-c-programming@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).