Great Deal! Get Instant $10 FREE in Account on First Order + 10% Cashback on Every Order Order Now

Problem 1: Write a program that creates multiple worker threads to calculate the sum of float point values saved in a file. Each thread calculates a partial sum, and the main thread adds up the...

1 answer below »

Problem 1:
Write a program that creates multiple worker threads to calculate the sum of float point values saved in a file. Each thread calculates a partial sum, and the main thread adds up the partial sums. Your program will read the float point values from a file and print out the sum on the screen. The number of worker threads, as well as the file containing the float point values, are specified in the command line.
For example.
problem_1 4 ./file_containing_values
You may use gendata.c attached with the assignment to generate the file. Your main thread can memory-map the file, such that the worker threads can access the float point values
in the file easily.
Problem 2:
Write a program that creates multiple processes to multiply two matrices of float point values. One matrix is saved in a file. The other matrix is an identity matrix
(https:
en.wikipedia.org/wiki/Identity_matrix) of the same size. Your program should save the product matrix into another file. Because the product should be the same as the first matrix, you can easily check whether your program produce co
ect results by comparing the product matrix against the first matrix. Use cmp command to compare (https:
linux.die.net/man/1/cmp).
The number of processes, the file containing the first matrix, and the file saving the product matrix, should be specified in the command line. The identity matrix should be generated dynamically ( determine the size based on the size of the input file (i.e., the one
containing the first matrix)).
problem_2 4 ./file_containing_one_matrix ./file_saving_product_matrix
You may use gendata.c attached with the assignment to generate the file for the first matrix. To ensure co
ectness, your program can assume that each matrix is square
(NxN). So, when you generate the input file, ensure that the number of float point values in the file is a square number (https:
en.wikipedia.org/wiki/Square_number).
To check the results, use cmp
cmp ./file_containing_one_matrix ./file_saving_product_matrix
Hint:
Your processes can memory-map the files to share data easily.
Refer to the multi-threaded matrix multiplication program in the slides for how to multiple two matrices in parallel.
Problem 3:
Write a program that create multiple processes to calculate an approximation of π. Refer to the multi-threaded program calculating an an approximation of π in the slides. The number of processes and the number of terms required to calculate the approximation should be specified in the command line (refer to the program in the slides). You may choose an IPC method (pipe, FIFO, or shm) you like in your implementation. But, pipe fits most. FIFO and shm are over-kills.

PowerPoint Presentation
Creating Threads - pthread_create()
#include int pthread_create (
pthread_t *thread,
variable to store returned thread ID
pthread_attr_t *attr,
thread attributes
void * (*start_routine)(void *),
function to run
void * arg);
args to pass to new thread
attr is to change the default thread attributes of the newly created thread
stack size, schedulizing parameters, and initial detached state
Most invocations of pthread_create() pass NULL for attr to use default attributes.
pthread_create() returns 0 if succeed.
On e
or, pthread_create() returns a nonzero e
or code directly (without the use of e
no) and the contents of thread are undefined.
7/27/2022
cs431-cotte
1
7/27/2022
cs431-cotte
1
#include #include #include * Global variables and data in heap are shared by all threads *
void * start_routine(void *id){ /* main func of a thread *
int *myid = (int *)id;
* private data defined in the function if there are any*
printf(“Greatings from thread %d\n”,*myid);
pthread_exit(NULL);
*thread ends when pthread_exit is called or the function ends*/
}
main(int argc, char *argv[]) {
/* main thread creates and controls new threads*
pthread_t thread[10]; int ret, i, index[10];
for (i=0;i<10;i++){
    index[i] = i;
ret = pthread_create(thread+i,NULL,start_routine,&(index[i]));
if (ret!=0) { e
no = ret; pe
or("pthread_create"); return -1;}
}
for (i=0;i<10;i++) pthread_join(thread[i], NULL);
}
Shared data and threads
Variables declared outside of main (global variables) are shared
Variables on the stack are private: passing pointer to these around to other threads can cause problems
Stack is released when a thread finishes; segmentation fault is caused if another thread still access private data in the stack.
Objects allocated on the heap may be shared,
if pointer is shared (i.e., pointer is global variable), o
If pointer is passed
Often done by creating a large “thread data” struct
Passed into a thread as the argument
char *message = "Hello World!\n";

pthread_create( &thread1, NULL,
XXXXXXXXXXvoid*)&print_fun,(void*) message);
Example: Passing Data
int i;
void *threadFunc(void *pArg)
{
int myNum = *((int *)pArg);
printf("Thread number %d\n", myNum);
}

from main():
for (i=0; i tNum[i]=i;
pthread_create(&tid[i], NULL, threadFunc, &tNum[i]);
}
What is the problem with the code?
int i;
void *threadFunc(void *pArg)
{
int myNum = *((int *)pArg);
printf("Thread number %d\n", myNum);
}

from main():
for (i=0; i pthread_create(&tid[i], NULL, threadFunc, &i);
}
void *do_work(void *arg) {
    struct arguments *argument;
    int i, size;
    double *a
ay;
    double *sum;
    argument = (struct arguments*)arg;

    size = argument->size;
    a
ay = argument->a
ay;
    sum = argument->sum;

    *sum = 0;
    for (i=0;i     *sum += a
ay[i];
    return NULL;
}
Another Example: share data and result by passing pointer
int main(int argc, char *argv) {
    double a
ay[100], sum;
    pthread_t worker_thread;
    struct arguments *arg;
    void *return_value;
    arg = (struct arguments *)calloc(1,sizeof(struct arguments));
    arg->a
ay = a
ay; arg->size=100; arg->sum = ∑
    if (pthread_create(&worker_thread, NULL, do_work,(void *)arg)) {
     fprintf(stde
,”E
or while creating thread\n”);
     exit(1);
    }
    ...
    if (pthread_join(worker_thread, &return_value)) {
     fprintf(stde
,”E
or while waiting for thread\n”);
     exit(1);
    }
        printf("%f\n", arg->sum);
}
Several ways a thread may be terminated
A thread returns from its start routine.
This is akin to a process finishes when returns from main().
A thread invokes pthread_exit()
This is akin to calling exit().
A thread is canceled by another thread via pthread_cancel()
This is akin to being sent the SIGKILL signal via kill().
The process terminates, and all the threads are killed
The process returns from its main() function.
The process terminates via exit().
The process executes a new binary image via exec…().
Terminating a thread
void pthread_exit (void *retval);
The calling thread terminates itself.
etval is provided to any thread waiting on the terminating thread’s death
int pthread_cancel (pthread_t thread);
pthread_cancel() sends a cancellation request to the thread.
Whether and when a thread is cancellable depends on its cancellation state and cancellation type.
Returns 0 if cancellation request is sent successfully; returns an e
or code if thread is invalid
Joining threads
int pthread_join (pthread_t thread, void **retval);
Joining allows one thread to block while waiting for the termination of anothe
if retval is not NULL, it saves the return value the terminated thread passed to pthread_exit() or returned from its start routine
All threads in Pthreads are peers; any thread may join any other.
On e
or, pthread_join() returns a nonzero e
or code.
common “bugs” that first-time pthread programmers make
pthread_join() is not called in main thread
the main thread may reach the end of main() and exit
other threads are killed when main thread finishes
It possible that they have NOT had a chance to compute a result
When creating multiple threads, store handles of different threads at different locations (avoid overwriting).
Typically use an a
ay of thread handles
One reason has been explained earlier.
The other reason is that way you’ll be able to call pthread_join() for each thread
Also, note that the following code is sequential!
    
for (i=0; i < num_threads; i++) {    pthread_create(&(threads[i]),...)
pthread_join(threads[i],...)
}
common “bugs” that first-time pthread programmers make
Another example: matrix multiply
            C = A × B
Sequential code:
For (i=0; i for (j=0; j for (k=0; kMulti-threaded matrix multiply
Do the same sequential operation, different threads work on different part of the C a
ay.
How to decide who does what? Need three parameters: N, nthreads, myid
From N, nthreads, myrank
I am responsiable for sub-a
ay
C[0..N-1][N/Nthreads*myrank..N/Nthreads*(myrank+1)-1]
The calculation of c[I,j] does not depend on other elements in C.
Thread 0 (myrank=0)
Thread Nthread -1
(myrank=Nthread-1)
#include double a[4000][4000], b[4000][4000], c[4000][4000];
int N, Nthreads, myid[200]; pthread_t tid[200];
void *mymm(void *arg) {
int myrank, i, j, k;
myrank = *(int *)arg;
for (i=0; i for (j=N/Nthreads*myrank; j <= N/Nthreads*(myrank+1)-1; j++)
for (k=0; k     c[i][j] = c[i][j] + a[i][k]*b[k][j];
}
int main(int argc, char * argv[]){
int i, j, k;
N = atoi(argv[2]); Nthreads = atoi(argv[1]);

for (i=0; i myid[i] = i;
pthread_create(&tid[i], NULL, &mymm, &myid[i]);
}
for (i=0; i pthread_join(tid[i], NULL);
return 0;
}
Multi-threaded PI calculation
Partition based on N, nthreads, and myid.
#include int myid[100], N, Nthreads; double sum[100], h;
pthread_t tid[200];
void *mycpi(void *arg) {
int myrank, i, j; double x;

myrank = *(int *)arg;
h = 1.0 / (double) N;
sum[myrank] = 0.0;
for(i=N/Nthreads*myrank+1; i<= N/Nthreads*(myrank+1);
i ++) {
x = h * ((double)i - 0.5);
Answered Same Day Jul 28, 2022

Solution

Aditi answered on Jul 28 2022
69 Votes
SOLUTION.PDF

Answer To This Question Is Available To Download

Related Questions & Answers

More Questions »

Submit New Assignment

Copy and Paste Your Assignment Here