Task #
Write a program which performs parallel operations on an array of
integers. Program takes n
(8 <= n <= 256
) and p
(1 <= p <= 16
) as arguments. Then it creates an array of
subsequent integers from 0
to n-1
. Parameter p
is the number of
working threads running at the same time.
After receiving SIGUSR1
program generates two random numbers a
and
b
(0 <= a < b <= n-1
) and spawns a new thread to perform
inversion on array - swap elements a
and b
, a+1
and b-1
, a+2
and b-2
etc. until
\(a+\lfloor\frac{b-a-1}{2}\rfloor\)
. After each swap
thread, wait 5ms. A single swap should be atomic (you should make sure
that swapped elements are not modified by different threads) - use mutex
per array element.
After receiving SIGUSR2
, the program spawns a new thread which prints
the state of the array. To print the array in a valid, existing state,
you should lock it whole (otherwise swapping threads can make changes
during printing).
If a new signal arrives when there are already p
working threads, the
program should print message All thread busy, aborting request
and
return to waiting. Working threads should be counted and monitored. When
one of the threads finishes its job, a new request can be processed.
Think about locking order to ensure operations safety and avoid deadlocks. You don’t need to (and you shouldn’t) perform redundant operations like swapping elements with itself.
You should not put heavy logic in signal handlers - only a few assignments or simple arithmetic operations are permitted. Any system functions are not permitted.
Stages:
Graded stages #
- Create array and mutexes as per task description. After receiving
SIGUSR1
, swaps are performed by the main thread. - Implement printing on
SIGUSR2
using new, detached thread. - Move swapping operation to a separate thread. Implement thread count limit logic.
- After receiving
SIGINT
(ctrl+c) program joins all threads and cleanly terminates.