<commit_before>==============================================================================
  1 - Micro-Shell
==============================================================================

(Question 1)
Our shell has to create two child processes after receiving a piped command,
one processes for the writing command and one process for the reading command.
One pipe has to be created for these processes to communicate (only in one
direction). The parent shell process waits for both child processes to finish
before reading the next command.

(Question 2)
This is not possible, because the necessary exec() call will destroy the
entire shell process (including any threads).

(Question 3)
You cannot use the cd command in our shell. The cd commands in shells are
built-in functions of these shells and not executable files.


==============================================================================
  2 - Synchronization
==============================================================================

(Question 4)
Mutual exclusion is needed here, because only one process at a time may be
calling the display() function. Mutual exclusion can be implemented with a
semaphore by initializing the semaphore to 1 and trying to DOWN() the
semaphore before entering the mutual exclusive code and do an UP() afterwards.
This way, only one process can be executing the mutual exclusive code at a
time because DOWN() on a semaphore with value 0 will be blocking until UP() is
called again.

  DOWN()
  mutex_code()
  UP()

(Question 5)
The difference with the previous exercise is that the two mutual exclusive
code blocks have to be executed alternatingly. In this case, events can be
used by a process to wait for authorization and to authorize the other process
to continue. Again, this can be implemented using semaphores, but this time we
need two of them. The first semaphore implements the event that the first
process may continue, while the second semaphore implements the event that the
second process may continue.
Each process authorizes the other process to continue execution by sending the
appropriate event after it has executed the relevant part of his code.

  DOWN(my_event)
  mutex_code()
  UP(his_event)
<commit_msg>Nog twee vragen ongeveer beantwoord.<commit_after>==============================================================================
  1 - Micro-Shell
==============================================================================

(Question 1)
Our shell has to create two child processes after receiving a piped command,
one processes for the writing command and one process for the reading command.
One pipe has to be created for these processes to communicate (only in one
direction). The parent shell process waits for both child processes to finish
before reading the next command.

(Question 2)
This is not possible, because the necessary exec() call will destroy the
entire shell process (including any threads).

(Question 3)
You cannot use the cd command in our shell. The cd commands in shells are
built-in functions of these shells and not executable files.


==============================================================================
  2 - Synchronization
==============================================================================

(Question 4)
Mutual exclusion is needed here, because only one process at a time may be
calling the display() function. Mutual exclusion can be implemented with a
semaphore by initializing the semaphore to 1 and trying to DOWN() the
semaphore before entering the mutual exclusive code and do an UP() afterwards.
This way, only one process can be executing the mutual exclusive code at a
time because DOWN() on a semaphore with value 0 will be blocking until UP() is
called again.

  DOWN()
  mutex_code()
  UP()

(Question 5)
The difference with the previous exercise is that the two mutual exclusive
code blocks have to be executed alternatingly. In this case, events can be
used by a process to wait for authorization and to authorize the other process
to continue. Again, this can be implemented using semaphores, but this time we
need two of them. The first semaphore implements the event that the first
process may continue, while the second semaphore implements the event that the
second process may continue.
Each process authorizes the other process to continue execution by sending the
appropriate event after it has executed the relevant part of his code.

  DOWN(my_event)
  mutex_code()
  UP(his_event)


==============================================================================
  3 - pthreads
==============================================================================

(Question 6)
We could also have used semaphores in the pthread version, just like we did in
the version with multiple processes. However, it would be a strange thing to
do: allocate shared memory for a semaphore while the two threads share most of
their variables anyway.


==============================================================================
  4 - Java threads
==============================================================================

(Question 7)
Yes.

{'fraction_non_alphanumeric': 0.210413833300952, 'fraction_numerical': 0.004274334563823586, 'mean_word_length': 5.532994923857868, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5247412', 'n_tokens_mistral': 1155, 'n_tokens_neox': 1044, 'n_words': 671}