Suppose we are having two threads. One prints "Hello" and other prints "World". We have to manage the threads in such a way that our program should print "Hello World" five times.
Can anyone suggests me the code or pseudocode for doing this ??
Thanks in advance.
I got the answer. I have used two binary semaphores, one for each function. Let two semaphores be first and second. Initially, first = 1 & second = 0. These values are selected because we want mutual exclusion along with no deadlocks. Algorithm:
printHello()
{
wait(first)
print "Hello"
signal(second)
}
printWorld()
{
wait(second)
print " World"
signal(first)
}
Related
I'd like to combine an mce_loop with threads created by threads->create, but fail. The simplified script below never reaches the second print line. Why?
(It works if I create the threads first, but in my real script this would make other parts more complicated).
use MCE::Loop;
mce_loop { } (0);
print "OK\n";
threads->create (sub {});
print "never reached ..\n";
With the help of the (later deleted) example posted by Håkon Hægland I figured out what really helps in my simplified example. I still don't get the reason for this strange behaviour.
use MCE::Loop;
mce_loop { } (0);
MCE->new ()->run; # this, but why?
print "OK\n";
threads->create (sub {});
print "never reached ..\n";
I remember back in college days, threads share resources and memory. I do not know the specifics of Raku implementation of threads, but if, at the same time, multiple threads call the same global function with different parameters, will they interfere one another because a global function is a single block of code shared by all the threads? E.g., this example does not show interference, but what about some complicated codes?
sub add ($a, $b) { $a + $b };
for 1..100 { start { sleep 1.rand; say "I am $_, {add($_, 1000)}"; } };
You should not have to worry about accessing a global function from multiple threads at the same time, in principle: arguments are passed by value, and parameters are lexical to the function.
There is one exception I can think of: using a state variable inside such a function. There is a known race-condition on the initialization of a state variable, and updates of the form $foo++ will most likely miss increments when being run from multiple threads at the same time. E.g.:
my int $a;
await (^10).map: { start { $a++ for ^100000 } }
say $a; # 893127
Aka, not the 1000000 you'd expect. Fortunately, to handle that case, we have atomic integers:
my atomicint $a;
await (^10).map: { start { $a⚛++ for ^100000 } }
say $a; # 1000000
But that's just showing off and not directly an answer to your question :-)
Should you have a piece of code that you want to make sure that only one thread executes at a time, you could use a Lock and the protect method on that;
my $lock = Lock.new; # usually in the mainline of a program
# ... code
$lock.protect: {
# code executed by only 1 thread at a time
}
Please note that this is considered to be "plumbing", aka use this only when you need to, as it opens you up to deadlocks.
I am not familiar with multi-thread and locks and atomic/nonatomic operations.
Recently I saw an interview question as below.
Put f1 and f2 in two separate threads and run them at the same time, when both of them return, what is the value of a?
int a = 2, b = 0, c = 0
func f1()
{
a = a * 2
a = b
}
func f2()
{
c = a + 11
a = c
}
I tried to implement the above code in objective c environment and what I got is a = 11. I'm not sure if this is right since what I did is put f1 in main queue and put f2 in a dispatch global queue and ran it async which could be incorrect.
If someone could give an answer and explain the process based on the level of register accessing, CPU processing, memory usage, that would be great.
The answer is - the result of A is random. It can be anything. Since access to A is not atomic and there is no synchronization, different threads might see a different value for a depending on random factors. If you manage to make a unaligned and run it on X86, you might even see a non-value for a.
I am just starting to learn the ins-and-outs of multithread programming and have a few basic questions that, once answered, should keep me occupied for quite sometime. I understand that multithreading loses its effectiveness once you have created more threads than there are cores (due to context switching and cache flushing). With that understood, I can think of two ways to employ multithreading of a recursive function...but am not quite sure what is the common way to approach the problem. One seems much more complicated, perhaps with a higher payoff...but thats what I hope you will be able to tell me.
Below is pseudo-code for two different methods of multithreading a recursive function. I have used the terminology of merge sort for simplicity, but it's not that important. It is easy to see how to generalize the methods to other problems. Also, I will personally be employing these methods using the pthreads library in C, so the thread syntax mildly reflects this.
Method 1:
main ()
{
A = array of length N
NUM_CORES = get number of functional cores
chunk[NUM_CORES] = array of indices partitioning A into (N / NUM_CORES) sized chunks
thread_id[NUM_CORES] = array of thread id’s
thread[NUM_CORES] = array of thread type
//start NUM_CORES threads on working on each chunk of A
for i = 0 to (NUM_CORES - 1) {
thread_id[i] = thread_start(thread[i], MergeSort, chunk[i])
}
//wait for all threads to finish
//Merge chunks appropriately
exit
}
MergeSort ( chunk )
{
MergeSort ( lowerSubChunk )
MergeSort ( higherSubChunk )
Merge(lowerSubChunk, higherSubChunk)
}
//Merge(,) not shown
Method 2:
main ()
{
A = array of length N
NUM_CORES = get number of functional cores
chunk = indices 0 and N
thread_id[NUM_CORES] = array of thread id’s
thread[NUM_CORES] = array of thread type
//lock variable aka mutex
THREADS_IN_USE = 1
MergeSort( chunk )
exit
}
MergeSort ( chunk )
{
lock THREADS_IN_USE
if ( THREADS_IN_USE < NUM_CORES ) {
FREE_CORE = find index of unused core
thread_id[FREE_CORE] = thread_start(thread[FREE_CORE], MergeSort, lowerSubChunk)
THREADS_IN_USE++
unlock THREADS_IN_USE
MergeSort( higherSubChunk )
//wait for thread_id[FREE_CORE] and current thread to finish
lock THREADS_IN_USE
THREADS_IN_USE--
unlock THREADS_IN_USE
Merge(lowerSubChunk, higherSubChunk)
}
else {
unlock THREADS_IN_USE
MergeSort( lowerSubChunk )
MergeSort( higherSubChunk )
Merge(lowerSubChunk, higherSubChunk)
}
}
//Merge(,) not shown
Visually, one can think of the differences between these two methods as follows:
Method 1: creates NUM_CORES separate recursion trees, each one having a single core traversing it.
Method 2: creates a single recursion tree but has all cores traversing it. In particular, whenever there is a free core, it is set to work on the "left child subtree" of the first node where MergeSort is called after the core is freed.
The problem with Method 1 is that if it is the case that the running time of the recursive function varies with the distribution of values within each initial subchunk (i.e. the chunk[i]), one thread could finish much faster leaving a core sitting idle while the others finish. With Merge Sort this is not likely to be the case since the work of MergeSort happens in Merge whose runtime isn't affected much by the distribution of values in the (sorted) subchunks. However, with a more involved recursive function, the running time on one subchunk could be much longer!
With Method 2 it is possible to have the same problem. Again, with merge sort its not clear since the running time for each subchunk is likely to be similar, but the line //wait for thread_id[FREE_CORE] and current thread to finish would also require one core to wait for the other. However, with Method 2, all calls to Merge run ASAP as opposed to Method 1 where one must wait for NUM_CORES calls to MergeSort to finish and then do NUM_CORES - 1 merges afterward (although you can multithread this as well...to an extent)
(though the syntax might not be completely correct)
Are both of these methods used in practice? Are there situations where one is more beneficial over the other? Is this the correct way to implement Method 2? (in this case, THREADS_IN_USE is a semaphore?)
Thanks so much for your help!
I found myself confronted with an interview question where the goal was to write a sorting algorithm that sorts an array of unsorted int values:
int[] unsortedArray = { 9, 6, 3, 1, 5, 8, 4, 2, 7, 0 };
Now I googled and found out that there are so many sorting algorithms out there!
Finally I could motivate myself to dig into Bubble Sort because it seemed pretty simple to start with.
I read the sample code and came to a solution looking like this:
static int[] BubbleSort(ref int[] array)
{
long lastItemLocation = array.Length - 1;
int temp;
bool swapped;
do
{
swapped = false;
for (int itemLocationCounter = 0; itemLocationCounter < lastItemLocation; itemLocationCounter++)
{
if (array[itemLocationCounter] > array[itemLocationCounter + 1])
{
temp = array[itemLocationCounter];
array[itemLocationCounter] = array[itemLocationCounter + 1];
array[itemLocationCounter + 1] = temp;
swapped = true;
}
}
} while (swapped);
return array;
}
I clearly see that this is a situation where the do { //work } while(cond) statement is a great help to be and prevents the use of another helper variable.
But is this the only case that this is more useful or do you know any other application where this condition has been used?
In general:
use do...while when you want the body to be executed at least once.
use while... when you may not want the body to be executed at all.
EDIT: I'd say the first option comes up about 10% of the time and the second about 90%. You can always re-factor to use either, in either circumstance. Use the one that's closest to what you want to say.
do...while guarantees that the body of code inside the loop executes at least once. This can be handy under certain conditions; when coding a REPL loop, for example.
Anytime you need to loop through some code until a condition is met is a good example of when to use do...while or while...
A good example of when to use do...while or while... is if you have a game or simulation where the game engine is continuously running the various components until some condition occurs like you win or lose.
Of course this is only one example.
The above posts are correct regarding the two conditional looping forms. Some languages have a repeat until form instead of do while. Also there's a minimalist view where only the necessary control structures should exist in a language. The while do is necessary but the do while isn't. And as for bubble sort you'll want to avoid going there as it's the slowest of the commonly known sorting algorithms. Look at selection sort or insertion sort instead. Quicksort and merge sort are fast but are hard to write without using recursion and perform badly if you happen to chose a poor pivot value.