Thread: Sharing sockets among threads

  1. #1
    Registered User
    Join Date
    Aug 2006
    Posts
    68

    Sharing sockets among threads

    Hi again
    I'll just drop the question: Can I get a socket (number) in another thread if I don't pass it when creating the thread? Like with a function or a procedure?

    Tia, Hawk

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Yes. You just need to use proper synchronization when sharing variables amoung threads.

    gg

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    And of course, you don't want to go reading one socket from more than one thread, whatever you do. Writing to the same socket from multiple threads will also be hard to make work [although possibly a little more manageable, as you at least have some control over what is going on].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    Quote Originally Posted by Codeplug View Post
    Yes. You just need to use proper synchronization when sharing variables amoung threads.

    gg
    Oh I mean when the socket variable in thread A is a local variable.

    Quote Originally Posted by matsp
    And of course, you don't want to go reading one socket from more than one thread, whatever you do.
    I really want to test that out. As for send()ing, after tests I know that I can send from both threads if I let thread B know the socket from thread A.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Sure, you CAN call send from multiple threads, but the result will not be "useful".

    Imagine you are sending the two strings:
    "Hello World"
    "Hi Universe"

    Now, you may end up with:
    "Hello World", "Hi Universe",
    or
    "Hi Universe", "Hello World"
    or
    "HHiell oUnWoivrldrse"

    Or just about any other combination of those two strings, depending on what the specific implementation of send does in your system.

    What, exactly do you think you would achieve by using two threads on the same socket?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    What about

    InitializeCriticalSection()
    TryEnterCriticalSection()
    LeaveCriticalSection()
    DeleteCriticalSection()

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Hawkin View Post
    What about

    InitializeCriticalSection()
    TryEnterCriticalSection()
    LeaveCriticalSection()
    DeleteCriticalSection()
    Yes, that would work, but then what is the benefit of using multiple threads? You don't actually gain anything if you are sitting around waiting for the other thread to finish sending/receiving something...

    Of course, if sending to the socket is only a tiny part of the overall work of the thread, but if that's the case, I would rather see a design where one thread is responsible for sending the data out, and one or more threads "doing work" - that way, you can (hopefully) continue working in the worker thread, whilst the "send" thread is sending the message. Even if you can't, it's a simple wait for the send complete event before you continue, so no need for rather clumsy critical sections, but a traditional request/wait pair.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    Maybe I can't follow your last post, but you said threaded send()s would cause mixed strings on the same socket as it would happen with printf()ing with 2 or more threads on the same stream. I have not tested if it would really mix it up but nevertheless with critical sections I can avoid stuff that could happen.

    And both threads should send() data.

    After further researches I found a way which finds the connected socket which I want to find. With this way I can only find all connected sockets and I can't distinguish between them if there are more than 1 connected sockets.

    With a getpeername() loop I check all sockets from within a acceptable range.

    I am surprised tough! If I create a program which connects only once to a server, say on socket 96, getpeername() also finds socket 97 and socket 98 as connected ones
    Also I can send on either 96, 97 or 98 just fine.

    Why's that? And is there a better method than with getpeername()?
    Last edited by Hawkin; 01-22-2008 at 12:06 PM.

  9. #9
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Don't loop on getpeername(). Just expose the data you need to your thread using a common shared pointer or a global variable. Use a critical section when reading and writting shared data.

    gg

  10. #10
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    It works, why shouldn't I use it? From the beginning I said I won't pass the socket descriptor, that's why I am having a problem and create this thread in the forums. If I passed it from the beginning I'd not have gotten into that topic and I had not learned anything, but now I know that there is getpeername() and how it works.
    Also I learned about critical sections.
    Also I found out that if I connect through 1 socket, I open 3 instead (which I still don't know why yet).

    That is what "pro coders" don't seem to get. I always get labled with "You don't need to because there is standardized stuff" or "Don't do that because it means some little extra work for you", maybe just because they don't know how to help? Or do they want to look down on me by telling me I shouldn't think of alternatives and try out new stuff? Or don't they want to help even if they knew how?
    Please let me know, I am dying to know about this... people keep doing it for years.

    And is there a better method than with getpeername()?
    That's what I've asked but as stated in the first post this sentence interpretatively means "are there better methods but passing the socket descriptor?"

    Please tell me why are you trying to lead me in another way rather than trying to help me reaching my goal?

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    What is your goal? If we know where you are heading, we can probably help you better, than if you ask questions about details of things: Asking "How do I remove a wheelnut?" or asking "How do I fix a flat tyre?" - which do you think will get your flat tyre fixed quicker? In your case you are asking if you can use send on multiple sockets, and I say that it is risky, and just because it happens to work on your system right now, doesn't mean that it's guaranteed to work on other systems.

    Yes, you can avoid thread-unsafe code by using critical sections - but the problem is that only one thread is allowed to run inside a critical section, so if you spend most of your time in your multiple threads inside the critical section (or waiting for the critical section) then the result is essentially the same as single threaded application, but with more overhead for handling the switching between threads and the critical section locking/unlocking - so you haven't actually gained anything.

    If on the other hand you are spending very little time sending through your socket, you probably should make the send call in another thread, and let the "work" threads do whatever calculations or similar that they do - this will help you get MORE work done, whilst the sending data thread is just sitting there waiting for more data to send most of the time.

    If your socket is actually connecting to a network [rather than internally within a single machine] then the slowest part of the transmission will be outside your machine, and no matter how many threads you have trying to pump data out of the machine, you will not achieve more than what your current network capacity is - in machines that doesn't have 10Gb/s network (or faster), this is normally done by a single thread on a machine with more than about 500MHz x86 processor.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> Just expose the data you need to your thread using a common shared pointer or a global variable
    Code:
    int global_data;
    
    void foo()
    {
        // access global_data
    }
    
    void bar()
    {
        // access global_data
    }
    >> Use a critical section when reading and writting shared data [between threads].

    gg

  13. #13
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    Just now I think I have reached nothing with my previous post - I appreciate that you guys spend your time trying to help me, but still you didn't touch the actual problem.

    Quote Originally Posted by matsp
    What is your goal? If we know where you are heading, we can probably help you better
    I already specified that in the first post, here's a list if you can't tell from post1:
    • I have one process.
    • I have two threads.
    • Thread1 is connected to anywhere.
    • Thread1 is only connected once.
    • Thread1 knows its socket descriptor but saved it in a local variable.
    • Thread2 needs to know on which socket descriptor Thread1 is connected on.
    • Thread2 has been created with no arguments.


    Maybe it's nice information if you talk about network speed or that my program will be that fast or that fast depending on how I use critical sections or that I "don't gain anything". <- This doesn't matter because the actual problem needs to be solved.

    You are going around my problem (again), and solving it IS my goal.

    Now I told you my goal (again), please take into account that only and really only this matters, other stuff is totally irrelevant as long as the main problem has not been solved.

    Codeplug: You also don't face my problem again by telling that I should pass the socket descriptor.

    I will stick with getpeername() if this doesn't lead to a solution. But thanks anyways for your time.
    Last edited by Hawkin; 01-23-2008 at 09:35 AM.

  14. #14
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    on windows - if you have a message queue on the second thread - you can use PostThreadMessage from the first thread to the second thread with the address of the variable
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Well, I'm concerned with the OVERALL problem, not transferring a handle/descriptor from one thread to another. If that's all you want to do, multiple suggestions have been made, including "using a global variable" - combine that with a suitable event/mutex/critsection to prevent problems with multiple threads.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 10-17-2008, 11:28 AM
  2. Programming chat client, need some help (sockets & threads)
    By lalilulelo17 in forum Linux Programming
    Replies: 1
    Last Post: 04-19-2008, 04:01 AM
  3. [newb] how to use threads with sockets ?
    By jabka in forum C Programming
    Replies: 1
    Last Post: 08-07-2007, 11:51 AM
  4. Library for pool, sockets, threads
    By Mortissus in forum C++ Programming
    Replies: 13
    Last Post: 07-14-2007, 07:41 AM
  5. Sockets and threads
    By karas in forum Linux Programming
    Replies: 4
    Last Post: 06-21-2007, 03:33 AM