By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,497 Members | 2,166 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,497 IT Pros & Developers. It's quick & easy.

*NIX sockets question

P: 86
I've started with socket programming and follow question arose:

If, in the server, I get a client/socket connection with function:

Expand|Select|Wrap|Line Numbers
  1. client_sockfd = accept( server_sockfd, (struct sockaddr *) &client_address, &client_len );
Then, is it a problem if I access later on this client_sockfd from two separate threads? Can I close() it from any of them?

I'm thinking of creating a thread to read() the socket and another separate one to write(), since I have asynchronous communication in both ways. Do I need to dup() client_sockfd, or just using the same absolute number for the separate threaded read() and write() is fine?
Nov 19 '08 #1
Share this Question
Share on Google+
8 Replies


weaknessforcats
Expert Mod 5K+
P: 9,197
Unless the documentation specifically says that this is thread safe, I would use the socket only from the creating thread.
Nov 19 '08 #2

P: 86
Unless the documentation specifically says that this is thread safe, I would use the socket only from the creating thread.
Aw... that was painful to read.

Seriously, there is no way I can use it from a separate thread? Currently I'm passing the fd number as argument of a new thread. It works. But don't know if me and my app will end up in developer's hell for that.

What about dup()? Would it help here?
Nov 19 '08 #3

Expert 100+
P: 2,415
Seriously, there is no way I can use it from a separate thread? Currently I'm passing the fd number as argument of a new thread. It works. But don't know if me and my app will end up in developer's hell for that.
Functions that aren't thread-safe can indeed be used from multiple threads and they will often appear to work fine. The problem is there are certain timing windows where execution in one thread damages another. The program fails sporadically; and the failure mode may be subtle or catastrophic.

If you're lucky you'll see some of these failures while you're testing . If you're not lucky, the failures won't start until you're demonstrating your code to somebody important (boss, teacher, customer,...).

Debugging one of these problems is typically very difficult. After all, there is no flaw in your program; the problem lies in a library function that you don't have the source code for.
Nov 19 '08 #4

P: 86
Functions that aren't thread-safe can indeed be used from multiple threads and they will often appear to work fine. The problem is there are certain timing windows where execution in one thread damages another. The program fails sporadically; and the failure mode may be subtle or catastrophic.

If you're lucky you'll see some of these failures while you're testing . If you're not lucky, the failures won't start until you're demonstrating your code to somebody important (boss, teacher, customer,...).

Debugging one of these problems is typically very difficult. After all, there is no flaw in your program; the problem lies in a library function that you don't have the source code for.
I'm aware of the problems of not mutexing things and so on and so forth, but what I'm worried here is about the specific issue:

"Is it possible to work on the same file descriptor (for a socket, if that's relevant) from several threads at the same time?"

If not, why not? How can I overcome this?

My problem is that I have to implement bidirectional communication, without no end being a master. I.e., each of the sides can start sending at any time, so I can't afford having a thread stuck at read(), since it won't be able to write() until read() is done (and read() will remain blocked most of the time).

I'm also aware that I can fcntl() the read so that it does not block on call. But that would mean busy-checking the input, and I have 23 threads more in my app demanding execution time.
Nov 19 '08 #5

Expert 100+
P: 2,415
I'm aware of the problems of not mutexing things and so on and so forth, but what I'm worried here is about the specific issue:

"Is it possible to work on the same file descriptor (for a socket, if that's relevant) from several threads at the same time?"

If not, why not? How can I overcome this?
Our point is that you're using socket library functions that you didn't write. If their documentation doesn't explicitly say they're thread-safe then you have no way of knowing if they are safe to use in multiple threads. They might be intrinsically thread-safe or they might not be (for instance, they might use static variables). On top of that, you can't make them thread-safe (by wrapping them with mutexes) unless you understand in what way they aren't thread-safe.

Go ahead and use them in multiple threads if you insist; but you can't ever be sure a failure isn't waiting for a good time to occur.
Nov 20 '08 #6

P: 86
Our point is that you're using socket library functions that you didn't write. If their documentation doesn't explicitly say they're thread-safe then you have no way of knowing if they are safe to use in multiple threads. They might be intrinsically thread-safe or they might not be (for instance, they might use static variables). On top of that, you can't make them thread-safe (by wrapping them with mutexes) unless you understand in what way they aren't thread-safe.
I'm using read(), write() and close(), which are syscalls. I don't know if in the background they're using socket library functions in my case. Are they?

Go ahead and use them in multiple threads if you insist; but you can't ever be sure a failure isn't waiting for a good time to occur.
I'm just defending my point as I see it. My concern is producing quality code, and for discussing something and getting at the top of an issue I have to follow some reasoning line. I can't tell my management "I'm not doing it like this because some guru suggested it might be wrong", and there is no evidence on why; specially if the change requested by the guru has a significant impact on overall performance. Give me a good reason and I'll change it.

Again, my feel is that it is more about how *NIX implements file descriptors rather than questioning the thread-safeness of read() and write(). You also think so?
Nov 20 '08 #7

Expert 100+
P: 2,415
My concern is a general one: I have no specific experience with sockets that would lead me to believe the related functions are or aren't thread-safe. I am reacting so strongly because I was burned badly many years ago when I learned the hard way that several functions in our vendor's Standard C Library weren't reentrant. (This was before the term "thread" gained currency.) It took me forever to track down the causes of the intermittent failures. Now I'm careful to check library documentation for claims of thread-safety. Another place to check is the POSIX standard -- I don't remember if it requires certain functions to be thread-safe, but it might. I'm perfectly willing to trust a vendor's claim for thread-safety; but I'm unwilling to assume thread-safety if they don't mention it.

My bad experience was with a cross-compiler we used to develop a foreground/background scheduler in an embedded system; where the library vendor may not have ever expected to face reentrant execution. Your question is about a *nix operating system that explicitly supports threads and processes. Perhaps my reflexive paranoa is uncalled for. You'll have to decide.
Nov 20 '08 #8

P: 86
Well, you weren't that paranoid. I found out documentation on my OS literally states: "A given socket can be read or written by only one task at a time".

So my will of having separate threads reading and writting is not possible. I'll have to think of something else.

The reason for my question was to take as much advantadge as possible of the OS services: If something is already solved by the OS there is no need to reinvent it, and sometimes it's not easy to find out the solution that best fits the available environment in a way that you don't need to reinvent the wheel.

Sockets appears to be one of this cases in which you have a thousand ways to solve the same problem, with the risk of implementing something with little performance at the expense of high processing requirements.

By now I'll try to implement it using select() syscall instead of my multiple thread approach. I've seen examples using select() to read from several open sockets in the same task, but not using select() to read and write, as I plan to do (so, I don't like it, for being a solution with no references). But I see no other choice (which I suspect is wrong and there might be around other things, but I don't find them).
Nov 21 '08 #9

Post your reply

Sign in to post your reply or Sign up for a free account.