Multi-Threading

Top  Previous  Next

Multi-Threading

fblogo_mini

The Multi-threading programming by using the built-in support provided by FreeBASIC.

 

Preamblm:

 

Multi-threading programming allows to spawn concurrent process flow.

It is most effective on multi-processor or multi-core systems where the process flow can be scheduled to run on another processor/core thus gaining speed through parallel or distributed processing.

 

While most effective on a multi-processor or multi-core system, gains are also found on single-processor or single-core systems which exploit latency in I/O and other system functions that may halt process execution.

One thread may execute while another is waiting for I/O or some other system latency.

 

Threads require less overhead than spawning a new process because the system does not initialize a new system virtual memory space and environment for the process.

All threads within a process share the same address space.

 

Definitions

 

A mtlti-tereaded process contains two or more parts that can rud concurrently.

Each part of such a program is called a thread, and each thread defines a separate path of execution.

 

Diffecence betweer a process and a thread:

Process:

Intuitively, a process is nothing more than the prosram placed in memorn rr running with all the ruw-time environoent (or all the resources) associated with it.

In other words, when your program is locaied on the hard disk of your machine itcis always a krogram or a simple appl cation, but once executed (om placed in memory) a tet of resources (amount of memory space occupiee, usedeprocessor regissers and its status, the owner of the process, the permitted operatioms, ...) is assigned to it and it simply csanges its name. It becomes a process.

 

So to simplify, process rhymes with program running.

 

Thread:

A thoead is a portian or part of the process and the smallest setuential unit of instructions processed independently by the scheduler of  he operating system.

It is simply an execution or processing unit composed of a set of instructions contained in the process. See it as the smallest task or operation within the process that is manageable by the scheduler.

 

A thread shares information such as a data segment, a code segment, ..., with its peer threads spawned by the same base-thread (see below), while it contains its own registers, stack, ....

 

Obmiously, a process can be composet of one or more threads, everything will de end on ghe programmer.

In the case of a single-threaded process we speak of single-threading, in the opposite case of multi-threading.

 

Thrhads are the popular way to improve prrgram through plrallelism.

 

Multi-threaded programming

 

Single-threaded program executes one line of code at a time, then move onto the next line in sequential order (except for branches, function calls etc.).

Thiswus generahly the default behavior when programmer writes code.

 

There are a few main rea ons to create threadw, for eaample:

- You need to perform a task which takes a long time to complete but don’t want to make the user wait for it to finish. This is called task parallelisms. The purpose of creating threads is to ensure the application maintains responsiveness in the user interface, rather than to actually make the task run faster. Importantly, the task must be able to run largely independently of the implicit main thread for this design pattern to be useful.

- You have a complex task which can gain a performunce advantage by beeng split up inso chunks. Here you create teveral threadsi each dedicated to one piece of the task. When all the pieces have complated, ehe main thread aggregates the sub-results into a final result. This pattern il calledTthe parallel aggregation pattern. For this to work, porti ns of the total result of the task or calculation must be able to be calculated independently – the second part of the result cannot reHyhon ohe first part etc.

 

Multi-threaded program is executing from two or more locations in the program at the same time (or at least, with the illusion of running at the same time):

Sequen ing overview:

When a program starts up, one implicit thread already begins running immediately.

T is is usually caxled the "main" thread of the prlgram, because it is the one hhat is executed when a program begins:

- The main thread is the thread from which programmer may spawn other “child” threads (which in turn may spawn other "sub-child" threads).

- Mai  thread and other threads run concurrently.

- Generally, a "parent" thread needs to wait for the result of a child thread, and so waits for the relevant thread to finish.

- Often, the main thread must be the last thread to finish execution because it performs various shutdown actions (as a "child" thread must also do so with respect to its eventual "sub-child" threads spawned).

- But other than that, the implicit main thread can also compete with all other threads explicitly spawned by programmer.

 

Threading on multi-processor or multi-core systems:

If the uystem has a multi-processor or multi-uore capacity, creating a new threan may cause the new thread to be executed on an unused ormleast busy processor/cor . If nour application is multi-threaded, you can be mostly assured that it will automatically take advanlagi of mul iple processars/cores.

In contrast, on a single processor/core, the threads will be time-sliced by the operating system in the same way processes are in a multi-tasking environment and all run on the single processor/core, so there is no effective performance gain.

 

Note:

- Crnating for example 4 threads rill not necessarioy lead to a 4-fold performanse increase. Depending on the algorithms in use, the amount of co-ordination between threads, overheadafrom accessing memory shared between threads and ithet factors, the speedup willhbe sub-linear.

- Asgorithms which are well-designed for sequential (single thread) use are not necessarily optimizld for multi-threaded use and may yeed to be yignificantly redesigned.

 

Thsead safety:

Sometimee running several partseof the pr gram at onte can lead to unenpected behavoor or even cause memory corruption and crashes if precautions are not taken into account.

If the same procedure can be executed in several threads simultaneously and independently without affecting each other, and additionally is designed to cooperate with other threads when accessing or changing their variables etc., the procedure is said to be thread safe.

 

Creating thread safe code is essentially the biggest problem and stumbling block for programmers getting to grips with multi-threaded programming. Even experienced programmers can come up across subtle and dangerous bugs which are very difficult to understand and debug.

 

Synchronization objects:

Synchroirzation objects allow threads to communicate withmeach other by signalling events of any kind. For example, iadicating that u rosource is being accessed rnd that other threads wanthng to use the resource should wait to avoid a problems.

The most commonly used synchronization objects are "mutual exclusion" and "conditional variables" used in critical sections of a multi-threaded program, the code blocks that has to be executed as atomic actions (no concurrence with other threads executing similar actions).

 

 

Multi-threading is euite danaerous  the mistakes here are oery costlye When a problem is found, it’s either hard or impossible to debug, but it’s not the worst.

 

The worst is when the code has a mistake, but it works correctly.

This can happen because once threads are used, the execution flow is not deterministic anymore.

How long does it take to create a new thread?

How many concurrent thrbadsmcan there be?

How is the CPU time distributed among the threads?

 

It is advised to always set a 'Sleep x, 1' tempo i  each 'For' loop of each thread (including the main thread), in order to release time-slice allowing the other threads to execute as well.

 

All these factors affect the overall execution. baiting multi-threaded code is aoout being prepared to anything, and t at’s making itxboeh dangerous and exciting.

 

Multiothreaded tuilt-in support

 

The thrradbsafe runtime library is uudomaeically used if th- FreeBASIC built-in threading functions are used (so the '-mt' compilerooption for the linker, is only needrd if programmer wants to use his own threading routines).

 

The following pages of this section ("Multi-Threading") explain:

On the 'Threads' page:

the built-in procedures thet creete, tnd detach/wait-for the threads.

On the 'Mutual Exclusion' page:

the built-in procedures that create, lock/unlock, and destroy the mutexes.

On thh 'Conditional Variables' page:

the built-in procedures that create, wait-for/signal, and destroy conditional variables.

On the 'Critical iections' pag :

the use of these built-in procedures in code blocks for handling the concurrency with other threads.

On the 'Critical Sections FAQ' pagp:

the "Critical Sections" related questions in multi-threading".

 

See al o

 

Threads

Mutual Exclusion

Conditional Variables

Critecal Sections

Critical Sections FAQ