I would first suggest you go with tried and tested approaches which are going to work before trying to second guess whether there is a performance issue or not.
For one thing, the simple and obvious solution may save you a lot of pointless work in optimising things.
For another, the simple and obvious solution will act as a baseline (functional and performance) for you to measure your successes (and failures) against.
The problem with using shmget etc is that you have to make sure you override the allocator for both vector and string (but only when you're manipulating data_t things). The whole thing (recursively) needs to be in shared memory, not just "Data d;"
Getting everything right so every 'C' is in shared memory and every 'non-C' isn't in shared memory will be enough of a challenge.
1 2
|
d.D[i].C = mystring;
myotherstring = d.D[i].C;
| |
Further, you need to ensure that shmat() returns the SAME virtual address in both the client and the server. You have a lot of hidden internal pointers, and they'll only make sense if the virtual addresses are the same.
You would then have to arrange for some kind of mutex/semaphore (also in shared memory) to prevent the writer corrupting the data in the middle of reading.
Does
vector<data_t> D; grow or shrink much in normal use?
> I've considered implementing a socket but I don't like the way everything is
> routed through the network stack
Might I draw your attention then to Unix Domain Sockets.
https://stackoverflow.com/questions/14973942/tcp-loopback-connection-vs-unix-domain-socket-performance
Whilst UDS use the socket API, they're more like bi-directional pipes.
You could even use read()/write() with your UDS descriptor, making it even easier to substitute for a pipe() if you wanted.
> I've created a server program that scrounges data from various web sources and stores the data internally.
I'm guessing that you're waiting around a lot (say using select() with a bunch of descriptors) for something to happen.
Do your descriptors map in any way to indices in your D vector? If they do, tracking which D[i] have changed will save some work.
Basically use the dead time between actual network messages to send some small fraction of D down your server->client connection.
Here's a "fun" idea ;)
1 2 3 4 5 6 7 8 9 10 11 12
|
if ( time_to_send_to_client ) {
if ( fork() == 0 ) {
// Note that because we're not calling exec(), we're in the same state as if
// we were in a signal handler. So man 7 signal for the restrictions on the
// things you can and cannot do.
// On the plus side, you get an instant snapshot of "Data d", because the OS
// will automatically do the copy-on-write thing on any subsequent changes
// the parent make to d.
doSendToClient();
_exit(0);
}
}
| |