Multithreaded 2d array input failing to produce output using pthreads in C - c

I created code to create a 2D table with threads but it won't run and I can't find a solution to this (I'm new to threads, and sorry for my bad English).
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_barrier_t our_barrier;
int done = 2;
void *threadfunc2(void *k) {
if (done != (int)*(int*)k) {
int n, d, i, j;
printf("give the 2d table dimensions \n");
scanf("%d", &n);
scanf("%d", &d);
int array[n][d];
for (i = 0; i < n; i++) {
for (j = 0; j < d; j++) {
scanf("%d", &array[i][j]);
}
}
for (i = 0; i < n; i++){
for (j = 0; j < d; j++){
printf("%d", array[i][j]);
}
}
pthread_barrier_wait(&our_barrier);
printf("Now finished!!!\n");
return NULL;
}
}
int main() {
int k = 1;
pthread_t tid1;
pthread_create(&tid1, NULL, threadfunc2, (void *)&k);
return 0;
}
I expected it to ask me to give the numbers for the 2D table but it won't do anything.

The moment main() returns, the process ends and the OS tears down all other threads belonging to the same process.
There are several options to avoid this behaviour:
Join the thread created in main() by calling pthread_join().
Leave main() by calling pthread_exit().
Make main() block until the thread spawned off did its work by using a set of condition- mutex- and status-variables.

Related

Making Ludo using Semaphores. 4 processes running sequentially like round robin

During this lockdown period, you are playing Ludo with your n number of family members where, n<=4. Assume that all the tokens are in the starting square and consider following scenarios: If the outcome of the dice is 6(six), then you can move your one token and get the chance to play dice again; otherwise, you can move your one token and give the dice to the next
player. Think of the players as processes which should be synchronized. You are
required to write a code for it using semaphore.
What I've tried is:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
sem_t *S;
pthread_mutex_t mutex;
int *play, n;
void check(int pid) {
six:
int num = (rand() % 6) + 1;
printf("Player %d rolled and got %d\n", pid + 1, num);
if(num == 6) goto six;
sem_post(&S[pid]); //only for next()
}
void roll(int pid) {
pthread_mutex_lock(&mutex);
check(pid);
pthread_mutex_unlock(&mutex);
sem_wait(&S[pid]);
}
void next(int pid) {
pthread_mutex_lock(&mutex);
int next = (pid+1)%n;
printf("Player %d passed the die to %d\n", pid + 1, next + 1);
check(next);
pthread_mutex_unlock(&mutex);
}
void *player(void *num) {
for (int i = 0; i < n; i++) {
roll(*((int *)num));
next(*((int *)num));
}
}
int main() {
printf("Enter No. of players : ");
scanf("%d",&n);
pthread_t pid[n];
pthread_mutex_init(&mutex, NULL);
S = malloc(n*sizeof(sem_t));
play = malloc(n*sizeof(int));
for(int i = 0; i < n; i++){
play[i] = i;
sem_init(&S[i], 0, 0);
}
for (int i = 0; i < n; i++)
pthread_create(&pid[i], NULL, player, &play[i]);
for (int i = 0; i < n; i++)
pthread_join(pid[i], NULL);
pthread_mutex_destroy(&mutex);
for (int i = 0; i < n; i++)
sem_destroy(&S[i]);
return 0;
}```
This is the output : https://i.stack.imgur.com/ZaNUC.png
I want to rectify the sequence by making the one rolling person is the one whom the die is passed.

Invalid type conversion in c threads, void* to int

First of all i hope you are all safe. I am trying to pass an array which contains the threadIDs of the threads created in C. I know the program is full of errors but I am getting one error that I don't know how to resolve. At the line where i write threadID[i]=(int*)tid[i]; I get invalid type conversion. What Im trying to do in convert void* to int and I get that error. I am pretty bad at C but I am trying to learn. If I could get any help I would appreciate it
Thank you
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
int x=0;
void* printMsg(void *tid)
{
pthread_t id = pthread_self();
int nthreads;
//Get the number of threads
nthreads= sizeof(tid);
//Copy thread array from main to threadID array
int *threadID[nthreads];
;
for(int i=0;i<nthreads;i++)
threadID[i]=(int*)tid[i];
if(pthread_equal(id,threadID[x]))
{
printf("%d\n",x);
x++;
}
while(1);
}
int main()
{
int i=0;
int n=0;
printf("Enter number of threads : ");
scanf("%d",&n);
pthread_t tid[n];
for(i=0;i<n;i++)
{
pthread_create(&(tid[i]), NULL, &printMsg, (void*)tid);
}
for (i=0;i<n;i++)
{
pthread_join(tid[i], NULL);
}
sleep(5);
return 0;
}
The ideal way to do this is to let the thread know which thread it is at creation time. You can do that by passing the thread ID as an argument. Here's a way you can do that:
void *printMsg(void *tnum_p) {
int tnum = *(int *)tnum_p;
printf("%d\n", tnum);
return NULL;
}
int main() {
int i = 0;
int n = 0;
printf("Enter number of threads: ");
scanf("%d", &n);
pthread_t tid[n];
int tnum[n];
for(i = 0; i < n; i++) {
tnum[i] = i;
pthread_create(&(tid[i]), NULL, &printMsg, &(tnum[i]));
}
for (i = 0; i < n; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}
One might think that we could just pass &i instead of &(tnum[i]); this would compile without any error, but then each thread would receive the same address, and it would be up to the luck and timing what each thread finds there (i.e. you'd almost certainly have repeated numbers).
(I also prefer tid + i and tnum + i instead of &(tid[i]) and &(tnum[i]), but that's just me.)
If you need to send any other information, then make a struct to carry everything you need, instead of passing an int.

Finding the square sum of an array with pthreads in C

What I need to do is calculate the square sum of an array. The array and the number of threads must be given by the user, and we assume the number of elements and the number of threads are integrally divided.
My code doesn't even compile.. I know I have issues with the pointers, and I should place mutexes but I don't know where exactly. Can you point me to the right direction? I will appreciate it a lot.
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
int part = 0;
int local_elements = 0;
void* square_sum(void* arg)
{
int local_sum = 0;
int *element_array[] = (int *)arg;
//Each thread computes its part
int thread_part = part++;
for (int i = thread_part * loc_elements; i < (thread_part + 1)*loc_elements; i++) {
local_sum += element_array[i] * element_array[i];
}
return (void*)&local_sum;
}
main()
{
int threads, total_elements;
int i;
int total_sum = 0;
printf("Give the number of threads: ");
scanf("%d", &threads);
printf("Give the number of the elements you want: ");
scanf("%d", &total_elements;)
int element_array[total_elements];
//How many elements each thread gets
local_elements = total_elements / threads;
printf("Give the %d elements \n", total_elements);
for (i = 0; i < total_elements; i++) {
printf("No. %d:", i);
scanf("%d", &element_array[i]);
}
pthread_t newthread[threads];
//Creating the threads
for (int i = 0; i < threads; i++) {
//The start routine gets the whole element_array
pthread_create(&newthread[i], NULL, square_sum, &element_array);
}
int loc_sum;
//Waiting for each thread to finish and creating the total_sum
for (int i = 0; i < threads; i++) {
pthread_join(newthread[i], &loc_sum);
total_sum += loc_sum;
}
printf("The total sum is: %d", &total_sum);
}

Sieve of Eratosthenes with multithreading in C/Linux

I am currently working on the calculation of the Eratosthenes Sieve using C multithreading.
The goal is to first create a main thread that uses a split function to divide the exploration of the numbers on a number of threads.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
void *creat_thread(int *nbThreads);
void *SieveEratosthenes(int *tailleTab);
int* tab;
int sizeTab;
int nbTachesParThread=0;
int main(void)
{
int nbThreads;
int n;
do{
printf("Enter an integer > 1 : ");
scanf("%d", &n);
} while(n<2);
sizeTab = n+1;
tab = (int*)malloc(tailleTab*sizeof(int));
for (unsigned int i=0; i<tailleTab; i++)
{
tab[i] = 1;
}
do{
printf("Enter a number positive number of threads : ");
scanf("%d", &nbThreads);
} while(nbThreads<1);
pthread_t threadPrincipal;
if (pthread_create(&threadPrincipal, NULL, creat_thread, NULL)) {
perror("pthread_create");
return EXIT_FAILURE;
}
if (pthread_join(threadPrincipal, NULL)) {
perror("pthread_join");
return EXIT_FAILURE;
}
printf("The Prime numbers are : \n");
for(unsigned int i=0; i<sizeTab; i++)
{
if(tab[i]==1)
{
printf("%d\n", (i));
}
}
}
void *creat_thread(int *nbThreads)
{
int nbTachesParThread = (int) sqrt(sizeTab) / nbThreads;
pthread_t* threads = (pthread_t*)malloc(nbThreads*sizeof(pthread_t));
int plageThreadi = nbTachesParThread;
for(int i = 0; i < nbThreads; ++i)
pthread_create (&threads[i], NULL, SieveEratosthenes, plageThreadi);
plageThreadi += nbTachesParThread;
}
void *SieveEratosthenes(int *plageThread)
{
for( int i=(plageThread - nbTachesParThread); i<=plageThread; i++)
{
if (tab[i] == 1)
{
for (int j = i*i; j<sizeTab; j += i)
{
tab[j]=0;
}
}
}
}
I tried to implement a code but I have an error at runtime:
segmentation error (core dumped)
On top of the issue mention in my comment here there is more to fix:
1st of all a PThread function needs to be of type void *(*)(void*). The ones used by the code are of type void *(*)(int*). Not good.
2ndly the code misses to join the work-threads, therefore the distributing thread ends after having created all workers, then it gets joined in main(), which then accesses the variables the workers are most likely are still working on causing undefined behaviour be doing so and then ends, ending the process. Ending the process cancels all worker-threads.
I followed your advice and created a structure to contain the variables that will be used by all threads.
However I noticed that sometimes it works (it displays the prime numbers well) but sometimes it doesn't work and it displays either only 0 or all the numbers from 0 to i.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
void *creat_thread(void* arg);
void *SieveEratosthenes(void* arg);
struct param
{
int* tab;
int sizeTab;
int nbTachesParThread;
int nbThreads;
int plageThreadi;
int plageThreadPrecedent;
};
int main(void)
{
struct param p;
int n;
do{
printf("Enter an integer > 1 : ");
scanf("%d", &n);
} while(n<2);
p.sizeTab = n+1;
p.tab = (int*)malloc(p.sizeTab*sizeof(int));
for (unsigned int i=0; i<p.sizeTab; i++)
{
p.tab[i] = 1;
}
do{
printf("Enter a number positive number of threads : ");
scanf("%d", &p.nbThreads);
} while(p.nbThreads<1);
pthread_t threadPrincipal;
if (pthread_create(&threadPrincipal, NULL, (void*)creat_thread, &p)) {
perror("pthread_create");
return EXIT_FAILURE;
}
if (pthread_join(threadPrincipal, NULL)) {
perror("pthread_join");
return EXIT_FAILURE;
}
printf("The Prime numbers are : \n");
for(unsigned int i=0; i<p.sizeTab; i++)
{
if(p.tab[i]==1)
{
printf("%d\n", i);
}
}
}
void *creat_thread(void* arg)
{
struct param *args = (void*)arg;
args->nbTachesParThread = (int) sqrt(args->sizeTab) / args->nbThreads;
pthread_t* threads = (pthread_t*)malloc(args->nbThreads*sizeof(pthread_t));
args->plageThreadi = args->nbTachesParThread;
for(int i = 0; i < args->nbThreads; ++i)
{
pthread_create (&threads[i], NULL, (void*)SieveEratosthenes, &(*args));
args->plageThreadPrecedent = args->plageThreadi;
args->plageThreadi += args->nbTachesParThread;
}
for(int i = 0; i < args->nbThreads; ++i)
{
pthread_join(threads[i], NULL);
}
pthread_exit(NULL);
}
void *SieveEratosthenes(void* arg)
{
struct param *args = (void *)arg;
for(int i=(args->plageThreadPrecedent); i<=args->plageThreadi; i++)
{
if (args->tab[i] == 1)
{
for (int j = i*i; j<args->sizeTab; j += i)
{
args->tab[j]=0;
}
}
}
pthread_exit(NULL);
}
In the main() function, move the calls to pthread_create() and pthread_join() outside of the if statement. These calls should be made regardless of whether or not the pthread_create() call succeeds.
In the SieveEratosthenes() function, the loop that marks composite numbers as 0 should start from i * i, not i. This is because any composite number can be written as the product of two prime numbers, and one of those prime numbers must be less than or equal to the square root of the composite number. Therefore, if a number i is composite, it must have a prime factor less than or equal to the square root of i.
In the creat_thread() function, move the call to pthread_join() inside the loop that creates the threads. This will ensure that each thread has completed before the next one is created.
In the creat_thread() function, initialize the plageThreadPrecedent variable to 2, since this is the first prime number.
I've modified my code so actually I have no more error code but once I have entered the 2 variables (number to calculate + number of threads), the program runs but displays nothing.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
void *creat_thread();
void *SieveEratosthenes();
int* tab;
int sizeTab = 0;
int nbTachesParThread=0;
int nbThreads = 0;
int plageThreadi = 0;
int plageThreadPrecedent = 0;
int main(void)
{
int n;
do{
printf("Enter an integer > 1 : ");
scanf("%d", &n);
} while(n<2);
sizeTab = n+1;
tab = (int*)malloc(sizeTab*sizeof(int));
for (unsigned int i=0; i<sizeTab; i++)
{
tab[i] = 1;
}
do{
printf("Enter a number positive number of threads : ");
scanf("%d", &nbThreads);
} while(nbThreads<1);
pthread_t threadPrincipal;
if (pthread_create(&threadPrincipal, NULL, creat_thread, NULL)) {
perror("pthread_create");
return EXIT_FAILURE;
}
if (pthread_join(threadPrincipal, NULL)) {
perror("pthread_join");
return EXIT_FAILURE;
}
printf("The Prime numbers are : \n");
for(unsigned int i=0; i<sizeTab; i++)
{
if(tab[i]==1)
{
printf("%d\n", (i));
}
}
}
void *creat_thread()
{
int nbTachesParThread = (int) sqrt(sizeTab) / nbThreads;
pthread_t* threads = (pthread_t*)malloc(nbThreads*sizeof(pthread_t));
int plageThreadi = nbTachesParThread;
for(int i = 0; i < nbThreads; ++i)
{
pthread_create (&threads[i], NULL, SieveEratosthenes, NULL);
pthread_join(threads[i], NULL);
plageThreadPrecedent = plageThreadi;
plageThreadi += nbTachesParThread;
}
for(int i = 0; i < nbThreads; ++i)
{
pthread_join(threads[i], NULL);
}
pthread_exit(NULL);
}
void *SieveEratosthenes()
{
for(int i=(plageThreadPrecedent); i<=plageThreadi; i++)
{
if (tab[i] == 1)
{
for (int j = i*i; j<sizeTab; j += i)
{
tab[j]=0;
}
}
}
pthread_exit(NULL);
}

multithreading - occasional segfault in matrix multiplication in c

I'm working on a small program of multithreaded matrix multiplication. My first job is to fill the entry of matrices with a random integer. I met some segment faults after I tried to pass a function pointer to pthread_create. And I think the problem is in function pthread_join.
But there are two issues in general.
The first one is the segment fault does not happen every time. Sometimes the code works, but most of the times it doesn't. So it really confuses me.
The other one is when the code is working, there are always several entries still not initialized, especially for matrix[0][0], it is never initialized. And I don't quite know where to debug that one.
Here's my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#define N 5
#define MAX 10
int A[N][N];
int B[N][N];
int C[N][N];
pthread_t pid[N][N];
typedef struct {
int row, col;
} Pos;
typedef void* (*thread_func)(void*);
void print_matrix(int M[][N]) {
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
printf("%3d", M[i][j]);
if (j < N - 1) {
printf(", ");
}
}
printf("\n");
}
}
void join_threads(void) {
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
pthread_join(pid[i][j], NULL);
}
}
}
void* fill_entry(void* arg) {
Pos* pos = (Pos*)arg;
A[pos->row][pos->col] = rand() % MAX;
B[pos->row][pos->col] = rand() % MAX;
return NULL;
}
void dispatch_jobs(thread_func job_func) {
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
Pos pos;
pos.row = i;
pos.col = j;
if (pthread_create(&pid[i][j], NULL, job_func, (void*)&pos)) {
perror("pthread_create");
exit(-1);
}
}
}
}
int main(void) {
srand(time(NULL));
dispatch_jobs(&fill_entry);
join_threads();
printf("Matrix A:\n");
print_matrix(A);
printf("Matrix B:\n");
print_matrix(B);
return 0;
}
Pos pos;
pos.row = i;
pos.col = j;
if (pthread_create(&pid[i][j], NULL, job_func, (void*)&pos)) {
perror("pthread_create");
exit(-1);
}
You are passing a pointer to a local variable to the threads. Once the thread tries to access the data, i.e. dereferences the pointer, the variable is long gone, reused, and contains garbage data.

Resources