Professional Documents
Culture Documents
Operating Systems
Laboratory Report 3
1
void isInsideCircle(struct Points graphPoint[], int size) {
double temp;
// SINGLETHREAD VERSION
if (argc != 2) {
fprintf(stderr, "Overflow of command argument!");
return -1;
}
if (atoi(argv[1]) <= 0) {
fprintf(stderr, "Size cannot be smaller than 1! Size
inputed: %d", atoi(argv[1]));
return -1;
}
generatePoints(graphPoint, atoi(argv[1]));
isInsideCircle(graphPoint, atoi(argv[1]));
2
– This main(int, char*) function takes in a command line of the total number of
generated points and purely call individual functions to perform the estimation.
– The following result is obtained:
– It can be seen that this program has a somewhat close estimation of the π =
3.148480 number when generating 1,000,000 entries.
However, at larger values, it cannot access (or increase) the array in general so it
throws Segmentation fault error.
Generally the single-threaded program has far close than accurate estimation of π
and does not work with larger sizes.
// MULTITHREAD VERSION
if (argc != 2) {
fprintf(stderr, "Overflow of command argument!");
return -1;
}
if (atoi(argv[1]) <= 0) {
fprintf(stderr, "Size cannot be smaller than 1! Size
inputed: %d", atoi(argv[1]));
return -1;
}
3
struct arguments* args;
args = malloc(sizeof(struct arguments) + (atoi(argv[1]) /
NUM_THREADS) * sizeof(struct Points));
args->size = atoi(argv[1]) / NUM_THREADS;
pthread_t threads[NUM_THREADS];
pthread_exit(0);
}
– This main\left( int, char* \right) function takes in a command line of the
total number of generated points and creates 10 different threads to each generate
a size/10 points and individually count up the number of inscribed points.
Afterwards, all threads wait for each other to finish execution via pthread_join(threads[t],
NULL) and print out the results.
– The following result is obtained:
4
– It can be seen that this program has a much closer estimation of the π number
when generating more than 1,000,000 entries. The production time is also faster
overall in comparison to the single-threaded version.
2 Concurrency
5
}
int main() {
pthread_t tid[10];
int i;
pthread_exit(NULL);
}
The above code causes race conditions when multiple threads are created as we don’t
know what process will the OS execute.
To fix this issue, we can either use pthread_join(threads[t], NULL) to wait for
thread execution one after another or implement a hard token, in which it can be passed
over, and the process which has the token in particular will be allowed to execute while
the other must wait for its turn.
pthread_mutext_t lock;
int main() {
pthread_t tid[10];
pthread_mutex_init(&lock, NULL);
int i;
6
pthread_exit(NULL);
}
This code implements a global pthread_mutex_t object, of which the variable lock
acts as lock to prevent execution from other threads beside the running one.
In the void* hello(void* tid) function, we can see that the function from the mutex
class pthread_mutex_lock(&lock) is called to “lock” the token to this thread so as
other threads cannot run concurrently. After it finishes execution, the lock is “unlocked”
via pthread_mutex_unlock(&lock) and the token will be passed to the next thread in
order.