Blocking IO vs non-blocking IO; looking for good articles [closed] - events

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
Once upon a time I bumped into Introduction to Indy article and can't stop thinking about blocking vs non-blocking IO ever since then.
Looking for some good articles describing what are pros and cons of blocking IO and non-blocking IO and how to design your application in each case to get natural, easy to understand and easy to maintain code.
Would like to understand BIG picture...

Well blocking IO means that a given thread cannot do anything more until the IO is fully received (in the case of sockets this wait could be a long time).
Non-blocking IO means an IO request is queued straight away and the function returns. The actual IO is then processed at some later point by the kernel.
For blocking IO you either need to accept that you are going to wait for every IO request or you are going to need to fire off a thread per request (Which will get very complicated very quickly).
For non-blocking IO you can send off multiple requests but you need to bear in mind that the data will not be available until some "later" point. This checking that the data has actually arrived is probably the most complicated part.
In 99% of applications you will not need to care that your IO blocks. Sometimes however you need the extra performance of allowing yourself to initiate an IO request and then do something else before coming back and, hopefully, finding that the IO request has completed.
Anyway, just my tuppence.
Edit: To answer how to design an application for handling blocking IO while have good performance, coroutines could be a good fit.

The positives and negatives are pretty clear cut:
Blocking - Linear programming, easier to code, less control.
Non-blocking - Parallel programming, more difficult to code, more control.

Related

Using operation queues with combine framework [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
With the arrival of combine framework, is there a need to use operation queues anymore. For example, apple uses operation queues almost all over the place in WWDC app. So if we use SwiftUI with combine(asynchronous programming), will there be a need to use Operation Queues?
Combine is just another asynchronous pattern, but doesn’t supplant operation queues (or dispatch queues). Just as GCD and operation queues happily coexist in our code bases, the same is true with Combine.
GCD is great at easy-to-write, yet still highly performant, code to dispatching tasks to various queues. So if you have something that might risk blocking the main thread, GCD makes it really easy to dispatch that to a background thread, and then dispatch some completion block back to the main thread. It also handles timers on background threads, data synchronization, highly-optimized parallelized code, etc.
Operation queues are great for higher-level tasks (especially those that are, themselves, asynchronous). You can take these pieces of work, wrap them up in discrete objects (for nice separation of responsibilities) and the operation queues manage execution, cancelation, and constrained concurrency, quite elegantly.
Combine shines at writing concise, declarative, composable, asynchronous event handling code. It excels at writing code that outlines how, for example, one’s UI should reflect some event (network task, notification, even UI updates).
This is obviously an oversimplification, but those are a few of the strengths of the various frameworks. And there is definitely overlap in these three frameworks, for sure, but each has its place.

How is distributed memory parallelism handled in Rust? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
How is distributed memory parallelism handled in Rust? By that, I mean language constructs, libraries, or other features to handle computing on something like a cluster akin to what MPI provides C, but not necessarily using the same primitives or methodology. In the Rustonomicon, I see a discussion of threads and concurrency, but I don't see any discussion on parallelizing across multiple computers.
To the best of my knowledge, there isn't really anything built into the language for distributed computing (which is understandable, since that's arguably not really the language's major focus, or at least wasn't back in the day). I don't believe there's any particularly popular crate or another for distributed computing either. Actix is probably the only actor crate that has achieved any traction, and it supports HTTP, but I don't think it is targeted at HPC/supercomputer setups. You also definitely would want to check out Tokio, which seems to be pretty much the library for asynchronous programming in Rust, and is specifically targeted towards network IO operations.
At the present point in time, if you're looking to replicate MPI, my guess would be that your best bet is to use FFI to a C-based MPI library. It appears that there's been a handful of attempts to create bindings to MPI for Rust, but I'm not sure that any of them are particularly complete.

Is it possible to use different garbage collection policies for Go? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
As the title says, I wonder if it is possible to change the GC policy used by the Go?
Not in the sense that you can use entirely different collectors like in Java or so on. This is on purpose; they want to get something that works decently well everywhere and avoid GC parameter tuning becoming a specialty for Go programmers.
The most often used option is GOGC. The default value of 100 essentially lets your program grow to twice the amount of live data it had after the last GC before another collection is triggered. 200 would let the program grow to 3x the live data after last GC, 50 would let it grow to only 1.5x. The exact timing and pacing of the collection is a little more complicated under the hood since 1.5 made GC concurrent, but the idea is still to target peak memory use of ~2x the amount of live data.
Practically speaking, the main use of GOGC I've seen is people increasing it to reduce a program's garbage collection workload when they know they have memory to spare. People have run the Go compiler with GOGC=400 or such for a little speedup, for instance. But note it's far more disastrous to bog down your servers by eating a lot of RAM than to spend a few percent more CPU time GC'ing, so don't go overboard with this.
The other knobs that exist are documented in package runtime. With the current implementation you can force GC's to be stop-the-world again or explicitly trigger potentially-stop-the-world collections with runtime.GC(). Separate from GC knobs, runtime also lets you ReadMemStats and get profiles, which are often useful.
You generally don't want to focus much on the little GC tuning possible; defaults work pretty well and your time is usually better spent thinking about your application.

Key reasons for golang to make concurrency easier [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Is my understanding roughly right below?
go can mostly detect dead lock at compile-time.
That go can use chan to minimize race condition is because only single sender or receiver goroutine can have access to any specific chan at a time.
I wouldn't say that's accurate. On the first point there aren't any compile time guarantees about dead locking, if you use a mutex poorly you will be dead locking, no compiler can prevent that. You can test for race conditions easily, but that's different.
On the second point, the channel serializes your asynchronous operations but I don't think how you state it makes much sense. A bunch of goroutines can be writing to and reading from it. It's just like a queue to put the data in, no coordination is guaranteed. You won't panic due to multiple routines reading off it or writing to it at the same time but if you have that happening Go isn't doing anything to make your program work well, you have to coordinate the routines yourself using channels.
No, the first is completely wrong and the second is at least stated unclear or strange.
According to this tutorial, it can catch some deadlocks. I've not gone though this tutorial though...
http://guzalexander.com/2013/12/06/golang-channels-tutorial.htmlenter link description here

Why is RAII so named? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
The sense I get about this idiom is that it is useful because it ensures that resources are released after the object that uses them goes out of scope.
In other words, it's more about de-acquisition and de-initialisation, so why is this idiom named the way it is?
First, I should note that it's widely considered a poorly named idiom. Many people prefer SBRM, which stands for Stack Bound Resource Management. Although I (grudgingly) go along with using "RAII" simply because it's widely known and used, I do think SBRM gives a much better description of the real intent.
Second, when RAII was new, it applied as much to the acquisition as releasing of resources. In particular, at the time it was fairly common to see initialization happen in two steps. You'd first define an object, and only afterwards dynamically allocate any resources associated with that object. Many style guides advocated this, largely because at that time (before C++ had exception handling) there was no good way to deal with failure in a constructor. Therefore, the style guides often said, constructors should do only the bare minimum of work, and specifically avoid anything that was open to failure -- especially allocating resources (and a few still say things like that).
Quite a few of those already handled releasing the resources in the destructor though, so that wouldn't have been as clear a distinction from previous practice.

Resources