The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,860 other subscribers

Archive for the ‘Multi-Threading / Concurrency’ Category

In potentially multi-threaded .NET Console applications, ensure `Console.EnsureInitialized` gets called for at least output, and potentially for input

Posted by jpluimers on 2024/07/02

An interesting issue at [Wayback/Archive] Khalid ⚡️: “I just used #JetBrainsRider to find a deadlock scenario in #dotnet that I would not have guessed would deadlock. The Console needs to be initialized since the initialization uses a lock the first time. Using it in parallel tasks causes deadlocks. #dotnet This is excellent tooling!…” – Mastodon.

https://i0.wp.com/web.archive.org/web/20240626133154if_/https%3A//files.mastodon.social/media_attachments/files/112/683/097/702/613/855/original/3c11b46a77d3a1fd.png

[Wayback/Archive] 3c11b46a77d3a1fd.png (2800×1610)

It boils down to a non-public Console.EnsureInitialized method being called from multiple threads causes deadlocks. So far, it looks it can only be called as part of referring to Console.In or Console.Out.

I could only find one potentially related bug, which is [Wayback/Archive] NativeRuntimeEventSource behaving poorly in conjunction with other providers · Issue #88011 · dotnet/runtime · GitHub and being worked on, for .NET 9 or later:

Read the rest of this entry »

Posted in .NET, Development, Multi-Threading / Concurrency, Software Development | Leave a Comment »

Lots of interesting programming learning games links via b0rk on Twitter

Posted by jpluimers on 2024/06/25

Every once in a while, b0rk (Julia Evans, of [Wayback/Archive] wizard zines fame) asks interesting questions like below that results in lot of cool links.

I have blogged assemblies of them before (see for instance Lots of interesting git links via b0rk on Twitter) and this one is no different:

[Wayback/Archive] Julia Evans on Twitter: “what are some helpful programming learning games? thinking of things like mystery.knightlab.com for SQL, and flexboxfroggy.com, and ohmygit.org especially interested in games that have helped you learn something”

The response was overwhelmingly good (I tried to indicate when games are not free or not playable from a web browser). I summarised it below.

Read the rest of this entry »

Posted in *nix, *nix-tools, Conference Topics, Conferences, CSS, Database Development, Development, DVCS - Distributed Version Control, Event, Games, git, Multi-Threading / Concurrency, Power User, RegEx, Scripting, sh, Sh Shell, Software Development, Source Code Management, SQL, Web Development | Leave a Comment »

Get it at a discount while it is hot: Delphi Thread Safety Patterns eBook by Dalija Prasnikar and Neven Prasnikar Jr.

Posted by jpluimers on 2022/06/01

Get the new [Wayback/Archive] Delphi Thread Safety Patterns eBook at a discount while it is hot:

Use Coupon Code: DTSPATT10 at checkout to get a $10 discount.
This promotional offer is valid through June 14.

Read the rest of this entry »

Posted in Delphi, Development, Encoding, ISO-8859, ISO8859, Mojibake, Multi-Threading / Concurrency, Software Development, UTF-8, Windows-1252 | Leave a Comment »

Some OmniThreadLibrary notes and links

Posted by jpluimers on 2021/07/14

For my link archive:

IOmniTimedTask and the Timed task name

You create a reference like this:

  TimedTask := Parallel.TimedTask.Execute(
    procedure(const task: IOmniTask)
    begin
      // ...
    end);

In the background, Parallel.TimedTask calls TOmniTimedTask.Create() which calls CreateTask(TOmniTimedTaskWorker.Create(), 'Timed task').Unobserved.Run

The problem is that TOmniTimedTaskWorker is private to the OtlParallel unit, which means you cannot take that call out without also copying that class.

There might be a workaround which I need to research based on the Apply method of IOmniTaskConfig, maybe through Parallel.ApplyConfig. These links might help:

–jeroen

Read the rest of this entry »

Posted in Delphi, Development, Multi-Threading / Concurrency, Software Development | Leave a Comment »

System.SyncObjs.TLightweightSemaphore.Create: the AInitialCount parameter

Posted by jpluimers on 2020/12/16

Multi-threading is hard, knowing your primitives is important, but Embarcadero documentation is always far from complete, leading to [WayBack] System.SyncObjs.TLightweightSemaphore.Create: Please simply explain to me the parameters of this constructor, especially first, AInitialCount… – Jacek Laskowski – Google+

The concept of semaphores is universal (the free book [WayBack] The Little Book of Semaphores – Green Tea Press is great), but the implementation/wrapping can slightly differ, so on the [Archive.is] XE introduced TLightweightSemaphore.Create parameters:

  • Primož Gabrijelčič's profile photo

    Semaphore is used to allow ‘counted’ access. It allows access to as much owners as it has maximum count. If you wait on a semaphore (WaitFor) and wait succeeds, the semaphore’s count is decremented. When it drops to 0, no new Wait will succeed.

    When you call Release, the semaphore’s count is incremented which allows somebody else to own the semaphore.

    Parameters simply set the initial state for this count and maximum value of the counter. Usually you’ll both set to the same value.

  • Primož Gabrijelčič's profile photo

    If you intend to use semaphores, read this. Great book.

    The Little Book of Semaphores – Green Tea Press
    greenteapress.com
  • Jacek Laskowski's profile photo
    I know (theoretically) how a semaphore works. I even used this semaphore class in production code.
    I want to create as many threads as there are cores in the processor (+ 1 additional, little loaded).fCoreController := TLightweightSemaphore.Create(TThread.ProcessorCount, TThread.ProcessorCount + 1);But now it turned out that customers who have CPUs with one core (yes, there are those), this code blocks the remaining threads. And I am looking for a reason, maybe I misunderstand this semaphore. What does AInitialCount mean?

    ps. Delphi Seattle

  • Stefan Glienke's profile photo
    AInitialCount is the number of entires a semaphore has left when created. If that is one less than AMaxCount that means you already gave one entry away. I just do a wild guess and say that you might do a Wait on the created semaphore shortly after creating it and in some other thread as well but since for one CPU your AInitialCount is only 1, one of them will block – possibly you created a deadlock situation here.
  • Jacek Laskowski's profile photo
    +Stefan Glienke Ok, if I want threads to be given a semaphore so that they work when it’s open (thread execute -> Semaphor.WaitFor) and I want to have as many threads as there are cores (+1 additional) then how should I create TLightweightSemaphore object?
  • Stefan Glienke's profile photo
    What Primoz said at the end of the very first comment – put same value for both: TThread.ProcessorCount + 1
  • Jacek Laskowski's profile photo

 

–jeroen

 

Posted in Delphi, Development, Multi-Threading / Concurrency, Software Development | Leave a Comment »

.NET Rocks: How do you do concurrency?

Posted by jpluimers on 2020/06/23

Since it was quite a while ago I wrote heavily concurrent code in .NET, I wanted to know about the starte of the art.

This pod cast and the book discussed in it helped a lot: [WayBackHow do you do concurrency? Carl and Richard talk to Riccardo Terrell about his book on Concurrency in .NET. https://www.manning.com/books/concurrency-i… – .NET Rocks! – Google+

Links referenced:

–jeroen

Posted in .NET, Development, Multi-Threading / Concurrency, Software Development | Leave a Comment »

Davidlohr Bueso on Twitter: A programmer had a problem. He thought to himself, “I know, I’ll solve it with threads!”. has Now problems. two he

Posted by jpluimers on 2020/05/27

When doing multi-threading, I’m always reminded of [WayBack/Archive.isDavidlohr Bueso on Twitter: A programmer had a problem. He thought to himself, “I know, I’ll solve it with threads!”. has Now problems. two he

Even with the advent of multi-core architectures long behind us (multi core hardware has been in a mature state for a long time), software for it often is not.

It is not just that programmers are not ready to do it (indeed often they are not: multi-threading is hard), but also that many pieces of software run perfectly fine in a single thread.

So when you do want to implement multi-threading, think twice.

It is one of the reasons I ported a C# version of the Deadlock Empire game (written in HTML + JavaScript) to generate Delphi code and examples. I was really glad that Dalija Prasnikar pointed to it in [WayBack] What is thread safety anyway?, and also pointed to the very important [WayBack] What is this thing you call “thread safe”? – Fabulous Adventures In Coding.

That last one stresses that multi-threading has vague definitions. It will stay vague because the problems you can encounter are virtually endless. There is no silver bullet: Lars Fosdal made this really nice remark in [WayBack] Multithreading can be hard to do right… – Dalija Prasnikar – Google+:

Locking too much is even worse than locking too little. It is very easy to deadlock with overly detailed locking. Applying locking in the wrong place, can serialize threads through a lock bottleneck.

Learning multithreading is a long series of mistakes that you probably can’t avoid, even if told about them up front. You are probably best off having to make the mistakes yourself and then learn from them ;)

To which Asbjørn Heid added:

… after a while I came to the realization that recursive locks are evil. They make it so easy to “just lock everything”. In contrast, non-recursive locks forces you to have explicit “thread-safety borders” in your code. And such borders really leads to better designs.

Here are the games:

Related:

–jeroen

 

 

Posted in Conference Topics, Conferences, Development, Event, Multi-Threading / Concurrency, Software Development | Leave a Comment »

Terminate threads during application or not?

Posted by jpluimers on 2019/10/02

I got an interesting question a while ago: should an application terminate (anonymous) threads or not?

A problem is that a thread might not execute unless you call WaitFor before Terminate is called. The reason is that the internal function ThreadProc does not start Execute if the thread is already terminated.

The ThreadProc in the System.Classes unit is an ideal place to set breakpoints in order to see which threads might start.

Other useful places to set breakpoints:

  • TAnonymousThread.Execute
  • TExternalThread.Execute

Execute not being called by ThreadProc is a bug, but it is not documented because QC is gone (taking the below entry with it), it is not in QP and the docwiki never got updated.

Given QC has so much information, I am still baffled that Embarcadero took it down.

Sergey Kasandrov (a.k.a. serg or sergworks) wrote in [WayBack] Sleep sort and TThread corner case | The Programming Works about this bug and refers to WayBack: QualityCentral 35451 – TThread implementation doesn’t guarantee that thread’s Execute method will be called at all .

The really bad thing are the WayBack: QualityCentral Resolution Entries for Report #35451 Resolution “As Designed” implying the design is wrong.

In his post, sergworks implemented the Sleep sorting in Delphi. Related:

Note that application shutdown is a much debated topic. Best is to do as little cleanup as possible: your process is going to terminate soon anyway. No need to close handles or free memory: Windows will do that for you anyway. See for instance:

 

Related to waiting:

Related to executing:

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Multi-Threading / Concurrency, Software Development, The Old New Thing, Windows Development | Leave a Comment »

Sometimes a race condition is in just two lines of code

Posted by jpluimers on 2019/07/30

A race condition can be this small:

if Assigned(Setting.OnChanged) then
  Setting.OnChanged(Setting);

If in between these lines, the value of Setting.OnChanged becomes nil, then you have an access violation.

It is a very slim, but real chance.

–jeroen

Posted in Delphi, Development, Multi-Threading / Concurrency, Software Development | 4 Comments »

Laptop fan profiling, and debugging them – related to Profiling | CommitStrip

Posted by jpluimers on 2019/07/23

A while back, I posted the “profiling” CommitStrip on[WayBack] Profiling – Jeroen Wiert Pluimers – Google+. Boy how did I not know that within a week, I bumped into a “laptop fan profiling” artefact.

A coworker noticed, that when starting a thread based equivalent of [WayBack] TTimer Class (which cannot be used in services as it depends on the VCL), then sometimes the laptop fans would spin up.

What basically happened was that for certain combinations of Enabled and Interval the Execute would loop burning 100% of one CPU core.

With 3 or more – sometimes 2 – of these threads active on a 4+4 core (4 are hyper-threaded), the processor fan would start to spin like madness.

Finding the solution was somewhat easy too:

  • Process Explorer would show the thread IDs burning the most CPU cycles
  • Delphi shows the Thread IDs in the Thread Status pane (if they are named, the ID is at the end of the name in parenthesis)
  • At around Delphi 2010, you can Freeze or Thaw threads. This allows you to debug only a single thread by freezing all others.

Focussing on one thread, allowed a close inspection of the loop, quickly finding the actual cause and repairing it.

TTimer Thread

A similar and better class is at [WayBack] multithreading – TTimerThread – Threaded timer class – Code Review Stack Exchange, based on [WayBack] timer – Using VCL TTimer in Delphi console application – Stack Overflow.

Read the rest of this entry »

Posted in Conference Topics, Conferences, Debugging, Delphi, Development, Event, Fun, Multi-Threading / Concurrency, Profiling-Performance-Measurement, Software Development | Leave a Comment »