I have never written any IPC C++ on Linux before.
My problem is that I will have multiple clients (writers), and a single server (reader). All of these will be on the same machine. The writers will deliver chunks of data (a string/struct) to the reader. The reader will then read them in FIFO and do something with them.
The types of IPC on Linux are either Pipes or Sockets/Message Queues as far as I can tell.
I was just wondering if someone could recommend me a path to go down. I'm leaning towards sockets, but I have no real basis for that. Is there anything I should read/understand before embarking on this journey?
Thanks
The main issue you should consider is what kind of data you are passing as this will in part determine your options. This comes down to whether your data is bounded or not. If it isn't bounded then something stream oriented like FIFOs or sockets are appropriate; if it is then you might make better use of of things like MQs or shared memory. Since you mention both strings and structs it is hard to say what is appropriate in your case, though if your strings are bounded within some reasonable maximum you can use anything with some minor fiddling.
The second is speed. There is never a completely correct answer for this but generally it goes something like: shared memory, MQs, FiFOs, domain sockets, network sockets.
The third is ease of use. Shared memory is the biggest PITA since you have to handle your own synchronization. Pipes are easy so long as your message lengths stay below PIPE_BUF size. The OS handles most of your headaches with MQs. Sockets are easy enough but you have the setup boilerplate.
Lastly several of the IPC mechanisms have both POSIX and SYSV variants. Generally POSIX is the way to go unless the SYSV type has some feature you really need or want.
EDIT: Count0's answer reminded me that you might be interested in something more abstract and higher level. In addition to ACE you can look at Poco. And, of course, no SO answer is complete if it doesn't mention Boost somewhere.
System V IPC is somewhat fiddly to use but it is a mature, robust technology. Message queues would probably do what you want and support atomic queuing/de-queuing.
Sockets are easy to use and also support communication over a network. However, they do not do any queuing, so you would have to write the queue management code within your server. Using sockets with C++ is not vastly different to using them with C. There are plenty of guides to this on the net and books such as Stevens' 'Unix Network Programming (vol 1)' that cover this topic in some depth.
A good place to get your feet wet is this sockets tutorial.
You'll then need to bone-up on threads & mutexes and here.
With the above you're all set to start playing ;-)
Though you've not asked for books, and because the answers above are so good, I'm only going to suggest you get your hands on copies of these two tomes:
UNIX Network Programming, Volume 2, Second Edition: Interprocess Communications, W. Richard Stevens
Advanced Programming in the UNIX Environment, Second Edition, W. Richard Stevens and Stephen A. Rago
There are inevitable ins & outs with this kind of coding, these two books will help you through whatever confusion you encounter.
Try to take a look at ACE (Adaptive Communication Environment). The ACE libraries are free available, very mature and cross platform. Unfortunately a good documentation is not, i would recommend this book to look for a good solution. You might try to take a look at this tutorial to get a feel of the patterns (at the end of the document). ACE uses a bunch of patterns to deal very successfully and efficient with those problems especially in a networked context, so it should be a good start to scope for good patterns and methods to use.
Especially Ace_Task using the Message_Queue allow to do what you need.
Related
I want to program (as efficiently as possible) a TCP/IP communication stack in C or C++. It really must run as fast as possible.
Does anyone have a good example or suggestion of where to start?
This is not meant as an insult, the guys who have developed the stacks for the well established operating systems have been doing this for years. This is what they do, unless you are in the business, I suggest you look at a different approach.
Different approach being, pick a stack that has decent performance (I hear that the latest tcp/ip stack in Solaris is nifty), then tune the hell out of it (there are lots of different flags and settings you can tune). If that fails to meet your needs, consider hardware solutions such as tcp offloading etc.
Writing your own stack, means you have to be confident enough to know that you can beat maybe 1000s of man years worth of effort in this field.
If this is for self development and learning, I suggest something simple like the source code for minix, it may have a simple to understand stack.
m2c.
This is a huge task. I would recommend the Contiki operating system as a possible starting point. It has a TCP/IP stack.
As Steve points out in the comments you do need quite a bit of experience to do this well. So rather than jumping directly to your end goal I recommend these possible steps:
Write a reliable transport using UDP as a normal user-land protocol.
Write a custom protocol using raw sockets in user-land.
Write a kernel level protocol module/driver
Write your stack on a FPGA network card
Linux is a good option as the details you need are easily accessible and documented.
And oh yeah, stop as soon as you realize you won't likely outperform the Linux kernel.
This may be worth looking at:
Implementing a High Performance Object Oriented TCP/IP Protocol Stack
Thesis for the Degree of Master of Science Peter Kjellerstedt and
Henrik Baard
lwip - A Lightweight TCPIP stack it's best to start learning about TCP/IP Stack
git clone git://git.savannah.nongnu.org/lwip.git
I'm currently writing a large multi threaded C++ program (> 50K LOC).
As such I've been motivated to read up alot on various techniques for handling multi-threaded code. One theory I've found to be quite cool is:
http://en.wikipedia.org/wiki/Communicating_sequential_processes
And it's invented by a slightly famous guy, who's made other non-trivial contributions to concurrent programming.
However, is CSP used in practice? Can anyone point to any large application written in a CSP style?
Thanks!
CSP, as a process calculus, is fundamentally a theoretical thing that enables us to formalize and study some aspects of a parallel program.
If you instead want a theory that enables you to build distributed programs, then you should take a look to parallel structured programming.
Parallel structural programming is the base of the current HPC (high-performance computing) research and provides to you a methodology about how to approach and design parallel programs (essentially, flowcharts of communicating computing nodes) and runtime systems to implements them.
A central idea in parallel structured programming is that of algorithmic skeleton, developed initially by Murray Cole. A skeleton is a thing like a parallel design pattern with a cost model associated and (usually) a run-time system that supports it. A skeleton models, study and supports a class of parallel algorithms that have a certain "shape".
As a notable example, mapreduce (made popular by Google) is just a kind of skeleton that address data parallelism, where a computation can be described by a map phase (apply a function f to all elements that compose the input data), and a reduce phase (take all the transformed items and "combine" them using an associative operator +).
I found the idea of parallel structured programming both theoretical sound and practical useful, so I'll suggest to give a look to it.
A word about multi-threading: since skeletons addresses massive parallelism, usually they are implemented in distributed memory instead of shared. Intel has developed a tool, TBB, which address multi-threading and (partially) follows the parallel structured programming framework. It is a C++ library, so probably you can just start using it in your projects.
Yes and no. The basic idea of CSP is used quite a bit. For example, thread-safe queues in one form or another are frequently used as the primary (often only) communication mechanism to build a pipeline out of individual processes (threads).
Hoare being Hoare, however, there's quite a bit more to his original theory than that. He invented a notation for talking about the processes, defined a specific set of signals that can be sent between the processes, and so on. The notation has since been refined in various ways, quite a bit of work put into proving various aspects, and so on.
Application of that relatively formal model of CSP (as opposed to just the general idea) is much less common. It's been used in a few systems where high reliability was considered extremely important, but few programmers appear interested in learning (yet another) formal design notation.
When I've designed systems like this, I've generally used an approach that's less rigorous, but (at least to me) rather easier to understand: a fairly simple diagram, with boxes representing the processes, and arrows representing the lines of communication. I doubt I could really offer much in the way of a proof about most of the designs (and I'll admit I haven't designed a really huge system this way), but it's worked reasonably well nonetheless.
Take a look at the website for a company called Verum. Their ASD technology is based on CSP and is used by companies like Philips Healthcare, Ericsson and NXP semiconductors to build software for all kinds of high-tech equipment and applications.
So to answer your question: Yes, CSP is used on large software projects in real-life.
Full disclosure: I do freelance work for Verum
Answering a very old question, yet it seems important that one
There is Go where CSPs are a fundamental part of the language. In the FAQ to Go, the authors write:
Concurrency and multi-threaded programming have a reputation for difficulty. We believe this is due partly to complex designs such as pthreads and partly to overemphasis on low-level details such as mutexes, condition variables, and memory barriers. Higher-level interfaces enable much simpler code, even if there are still mutexes and such under the covers.
One of the most successful models for providing high-level linguistic support for concurrency comes from Hoare's Communicating Sequential Processes, or CSP. Occam and Erlang are two well known languages that stem from CSP. Go's concurrency primitives derive from a different part of the family tree whose main contribution is the powerful notion of channels as first class objects. Experience with several earlier languages has shown that the CSP model fits well into a procedural language framework.
Projects implemented in Go are:
Docker
Google's download server
Many more
This style is ubiquitous on Unix where many tools are designed to process from standard in to standard out. I don't have any first hand knowledge of large systems that are build that way, but I've seen many small once-off systems that are
for instance this simple command line uses (at least) 3 processes.
cat list-1 list-2 list-3 | sort | uniq > final.list
This system is only moderately sized, but I wrote a protocol processor that strips away and interprets successive layers of protocol in a message that used a style very similar to this. It was an event driven system using something akin to cooperative threading, but I could've used multithreading fairly easily with a couple of added tweaks.
The program is proprietary (unfortunately) so I can't show off the source code.
In my opinion, this style is useful for some things, but usually best mixed with some other techniques. Often there is a core part of your program that represents a processing bottleneck, and applying various concurrency increasing techniques there is likely to yield the biggest gains.
Microsoft had a technology called ActiveMovie (if I remember correctly) that did sequential processing on audio and video streams. Data got passed from one filter to another to go from input to output format (and source/sink). Maybe that's a practical example??
The Wikipedia article looks to me like a lot of funny symbols used to represent somewhat pedestrian concepts. For very large or extensible programs, the formalism can be very important to check how the (sub)processes are allowed to interact.
For a 50,000 line class program, you're probably better off architecting it as you see fit.
In general, following ideas such as these is a good idea in terms of performance. Persistent threads that process data in stages will tend not to contend, and exploit data locality well. Also, it is easy to throttle the threads to avoid data piling up as a fast stage feeds a slow stage: just block the fast one if its output buffer grows too big.
A little bit off-topic but for my thesis I used a tool framework called TERRA/LUNA which aims for software development for Embedded Control Systems but is used heavily for all sorts of software development at my institute (so only academical use here).
TERRA is a graphical CSP and software architecture editor and LUNA is both the name for a C++ library for CSP based constructs and the plugin you'll find in TERRA to generate C++ code from your CSP models.
It becomes very handy in combination with FDR3 (a CSP refinement checker) to detect any sort of (dead/life/etc) lock or even profiling.
I wanted to know how to go about implementing semaphores, locks and condition variables in C/C++. I am learning OS concepts but want to get around implementing the concepts in C.
Any tutorials?
Semaphores, locks, condition variables etc. are operating system concepts and must typically be implemented in terms of features of the operating system kernel. It is therefore not generally possible to study them in isolation - you need to consider the kernel code too. Probably the best way of doing this is to take a look at the Linux Kernel, with the help of a book such as Understanding The Linux Kernel.
Semaphore at the very simplest is just a counter you can add and subtract from with a single atomic operation. Wikipedia has an easy to understand explanation that pretty much covers your question about them:
http://en.wikipedia.org/wiki/Semaphore_(programming)
A good starting point for learning OS concepts is probably Andrew Tanenbaum's "Modern Operating Systems". He also has another book on his own OS (Minix), which is called "Operating Systems: Design and Implementation" which goes more into detail about coding. You should be able to find those books in your local library.
Related topics you might want to look up to get the grip on how and why to use semaphores: race conditions, synchronization, multithreading, consumer-producer-problem.
At the ground level, if you want to implement that sort of thing, you're going to need to use assembly language. C and C++ simply don't expose the sort of features necessary to write concurrent code --- except by using libraries, which use assembler in their implementation.
The minix stuff is pretty good. A simpler example is the MicroC/OS stuff. It comes with a textbook that goes into good detail, all the source is there. It has the basic elements there and the code is small enough that you can understand it in a relatively short period of time.
http://www.micrium.com/products/rtos/kernel/rtos.html
http://en.wikipedia.org/wiki/MicroC/OS-II
Another thing you can do, is make a faked out OS in an application on linux. I did this by setting up the basic tick with an itimer, then swapping threads around with the function call swapcontext (man 2 swapcontext) which will save the regs on the stack. That gets the ugly stuff out of the way and you are left to implement the semaphores/mutexes/timers and all that. It was quite fun.
Despite what some of the posts say, assembler is not required. A knowledge of it will always help. It never hurts to understand how the internals/complilers/etc work when you are writing even high level applications.
For basic understanding, you can refer book Operating System Concepts, by Avi Silberschatz, Peter Baer Galvin, Greg Gagne and is really good.
You can also visit Dave Marshall's site for some support. Refer Semaphore section there.
Funny, Stevens Book is one of the classic texts for describing the use of synchronisation primitives and their uses. He certainly seems to think they can be used to control inter process communication. I tend to agree with him. Networking, no, IPC yes. most certainly yes.
You can catch up with alot of IPC( Inter Process Communication) Books, that can explain the ins and outs of what you need. There is one classic book. Unix Network Programming Inter Process Communication by Richard Stevens. you will get all you need. :)
a theoretical question. After reading Armstrongs 'programming erlang' book I was wondering the following:
It will take some time to learn Erlang. Let alone master it. It really is fundamentally different in a lot of respects.
So my question: Is it possible to write 'like erlang' or with some 'erlang like framework', which given that you take care not to create functions with sideffects, you can create scaleable reliable apps as well as in Erlang? Maybe with the same msgs sending, loads of 'mini processes' paradigm.
The advantage would be to not throw all your accumulated C/C++ knowledge over the fence.
Any thoughts about this would be welcome
Yes, it is possible, but...
Probably the best answer for this question is given by Robert Virding’s First Rule:
“Any sufficiently complicated
concurrent program in another language
contains an ad hoc,
informally-specified, bug-ridden, slow
implementation of half of Erlang.”
Very good rule is use the right tool for the task. Erlang excels in concurrency and reliability. C/C++ was not designed with these properties in mind.
If you don't want to throw away your C/C++ knowledge and experience and your project allows this kind of division, good approach is to create a mixed solution. Write concurrent, communication and error handling code in Erlang, then add C/C++ parts, which will do CPU and IO bound stuff.
You clearly can - the Erlang/OTP system is largely written in C (and Erlang). The question is 'why would you want to?'
In 'ye olde days' people used to write their own operating system - but why would you want to?
If you elect to use an operating system your unwritten software has certain properties - it can persist to hard disk, it can speak to a network, it can draw on screens, it can run from the command line, it can be invoked in batch mode, etc, etc...
The Erlang/OTP system is 1.5M lines of code which has been demonstrated to give 99.9999999% uptime in large systems (the UK phone system) - that's 31ms downtime a year.
With Erlang/OTP your unwritten software has high reliability, it can hot-swap itself, your unwritten application can failover when a physical computer dies.
Why would you want to rewrite that functionality?
I would break this into 2 questions
Can you write concurrent, scalable C++ applications
Yes. It's certainly possible to create the low level constructs needed in order to achieve this.
Would you want to write concurrent, scalable, C++ applications
Perhaps. But if I was going for a highly concurrent application, I would choose a language that was either designed to fill that void or easily lent itself to doing so (Erlang, F# and possibly C#).
C++ was not designed to build highly concurrent applications. But it can certainly be tweaked into doing so. The cost might be higher than you expect though once you factor in memory management.
Yes, but you will be doing some extra work.
Regarding side effects, consider how the .net/plinq team is approaching. Plinq won't be able to enforce you hand it stuff with no side effects, but it will assume you do so and play by its rules so we get to use a simpler api. Even if the language doesn't have built-in support for it, it will still simplify things as you can break the operations more easily.
What I can do in one Turing complete language I can do in any other Turing complete language.
So I interpret your question to read, is it as easy to write a reliable and scalable application in C++ as it is in Erlang?
The answer to that is highly subjective. For me it is easier to write it in C++ for the following reasons:
I have already done it in C++ (at least three times).
I don't know Erlang.
I have read a great deal about Stackless Python, which feels to me like a highly concurrent message based cooperative multitasking system in python, but of course python is written on top of C.
Having said that. If you already know both languages, and you have the problem well defined, you can then make the best choice based on all the information you have at hand.
the main 'problem' with C (or C++) for writing reliable and easy to extend programs is that in C you can do anything. so, the first step would be to write a simple framework that restricts just a bit. most good programmers do that anyway.
in this case, the restrictions would be mostly to make it easy to define a 'process' within whatever level of isolation you want. fork() has a reputation of being slow, and threads also need significant time to spawn, so you might want to use a cooperative multitasking, which can be far more efficient, and you could even make it preemptive (i think that's what Erlang does). to get multi-core efficiency, set a pool of threads and make all of them complete to run the tasks.
another important part would be to create an appropriate library of immutable data structures, so that using them (instead of the standard lib) your functions would be (mostly) side-effect-free.
then it's just a matter of setting a good API for message passing and futures... not easy, but at least it doesn't seem like changing the language itself.
When I hire developers for general mid-to-senior web app development positions, I generally expect them to understand core concurrent programming concepts such as liveness vs. safety, race conditions, thread synchronization and deadlocks. I'm not sure whether to consider topics like fork/join, wait/notify, lock ordering, memory model basics (just the basics) and so forth to be part of what every reasonably seasoned developer ought to know, or whether these are topics that are more for semi-specialists (i.e. developers who have made a conscious decision to know more than the average developer about concurrent programming).
I'd be curious to hear your thoughts.
I tend to think that at this point in time concurrent programming at any serious level of depth is still a specialist skill. Many will claim to know about it through study, but many will also make an almighty mess of it when they come to apply it.
In addition to the considerations listed, I would also look at resource implications and the various overheads of using processes, threads and fibers. In some contexts, e.g. mobile devices, excessive multithreading can have serious performance implications. This can lead to portability issues with multithreaded code.
I guess if I was interviewing a candidate in this situation, I would work with a real world example rather than hitting on more general topics which can be quoted back verbatim from a text book. I say this having done a fair bit of multithreaded work myself and remembering how badly I screwed up the first couple of times. Many can talk the talk... ;)
I know all these topics, but I studied them. I also know many competent senior programmers that don't know these. So unless you expect these programmers to be using those concepts actively, there is no reason to turn down a perfectly good candidate because they don't understand every aspect of concurrency
The real question is:
In what ways does it matter to the code they will be developing?
You should know which concepts the development position you're hiring for needs to know to be able to work on the projects that they will be responsible for.
As with anything in the programming world.. The devil is in the details, and you can't know everything. Would you expect them to know Perl if you were hiring for a Java position?
Also, concurrency, at this stage, while well described in generalized theory, is heavily implementation and platform dependent. Concurrency in Perl on an AIX box is not the same game as concurrency in a C++ Winforms app. They can have all the theory in the world under their belts, but if it's required for the job, then they should have intimate knowledge of the platform they are expected to use it on as well.
I interview folks for concurrency-related positions frequently and I look for three general aspects:
General understanding of core concepts like the ones you list (language-independent)
Specific understanding of Java concurrency libraries and primitives (specific to the work they'd be doing)
Ability to design the solution to a concurrent problem in a reasonable way.
I consider #1 a requirement (for my positions). I consider #2 a nice to have. If they understand it and can describe it in terms of pthreads or whatever other library, it's no biggie to learn the latest Java concurrency libraries (the concepts are the hard part). And #3 tends to separate the hires from the maybe-hires.
Per your question, I wouldn't consider fork/join to be known by almost anyone, esp someone applying for a web app developer position. I would look for developers to have experience with some (but not all) of those topics. Most developers I've interviewed have not used the Java 5+ concurrency libs at all but they can typically describe things like data race or deadlock.