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);
}
Related
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.
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.
This is a program to make the (square) sum of an array using threads. It works fine if the array elements are up to about 2.000.000 but after that I get a "Segmentation fault (core dumped)" error. Could it be because I am using ubuntu in a virtual machine and I have allocated 4GB of RAM in it?
Thank you for your time!
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
int part = 0;
int local_elements = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* square_sum(void* arg);
int main()
{
int threads, total_elements;
int i;
void *loc_sum = NULL;
long long total_sum = 0;
printf("Give the number of threads: ");
scanf("%d", &threads);
/*-----Fixed big size array-----*/
total_elements = 2000000; // <--- If this value gets big I get that error
local_elements = total_elements/threads;
int element_array[total_elements];
for (int i=0; i<total_elements; i++) {
//Filling all the positions with 1s
element_array[i] = 1;
}
//Creating the threads
pthread_t newthread[threads];
for (int i=0; i<threads; i++) {
//The thread function gets the element array
pthread_create(&newthread[i], NULL, square_sum, (void *)element_array);
}
//Waiting for each thread to finish and creating the total_sum
for (int i=0; i<threads; i++) {
pthread_join(newthread[i], (void*) &loc_sum);
printf("Thread %d returned the local_sum: %d \n", i, (int)loc_sum);
total_sum += (int)loc_sum;
}
printf("\nThe total square sum of the array is: %lld\n", total_sum);
return 0;
}
void* square_sum(void* arg) {
intptr_t local_sum = 0;
int *element_array = (int *) arg;
//--- Start of critical section ---
pthread_mutex_lock(&mutex);
//Each thread computes its part
int thread_part = part++;
for (int i = thread_part*local_elements; i < (thread_part+1)*local_elements; i++) {
local_sum += element_array[i] * element_array[i];
//printf("Thread %d says -- element %d is: %d \n", thread_part, i, element_array[i]);
}
pthread_mutex_unlock(&mutex);
//--- End of critical section ---
return ((void*)local_sum);
}
Kiran Biradar is correct. I get correct results with ulimit -s 80000 (I ran as root to set high ulimit) for this hacked version of your program. Alternatively, allocating the array on the heap or as static should also avoid the stack size problem, as mentioned by another commenter.
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
int part = 0;
int local_elements = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* square_sum(void* arg) {
int* local_sum = (int*)malloc(sizeof(int));
int *element_array = (int *) arg;
//--- Start of critical section ---
pthread_mutex_lock(&mutex);
//Each thread computes its part
int thread_part = part++;
for (int i = thread_part*local_elements; i <
(thread_part+1)*local_elements; i++) {
*local_sum += element_array[i] * element_array[i];
//printf("Thread %d says -- element %d is: %d \n", thread_part, i,
//element_array[i]);
}
pthread_mutex_unlock(&mutex);
//--- End of critical section ---
return local_sum;
}
int main()
{
int threads, total_elements;
int i;
int* loc_sum;
long long total_sum = 0;
printf("Give the number of threads: ");
scanf("%d", &threads);
/*-----Fixed big size array-----*/
total_elements = 2000000; // <--- If this value gets big I get that error
local_elements = total_elements/threads;
int element_array[total_elements];
for (int i=0; i<total_elements; i++) {
//Filling all the positions with 1s
element_array[i] = 1;
}
//Creating the threads
pthread_t newthread[threads];
for (int i=0; i<threads; i++) {
//The thread function gets the element array
pthread_create(&newthread[i], NULL, square_sum, element_array);
}
//Waiting for each thread to finish and creating the total_sum
for (int i=0; i<threads; i++) {
pthread_join(newthread[i], (void**)&loc_sum);
printf("Thread %d returned the local_sum: %d \n", i, *loc_sum);
total_sum += *(int*)loc_sum;
free(loc_sum);
printf("loc_sum %d\n", *loc_sum);
}
printf("\nThe total square sum of the array is: %lld\n", total_sum);
return 0;
}
Your problem is that
int element_array[total_elements];
is too big to be allocated in the in the stack. 2.000.000 positions requires 8Mb of memory, and Linux's default stack size is 8Mb, as can be seen by running ulimit -s. To fix it, you can use malloc to allocate it in the heap, or use the static keyword, as it will allocate the array in the .data segment, which usually has a 4Gb limit in amd64 machines.
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);
}
I was trying to write a program that calculates prime numbers using threads and the program was working but not giving the desired results (it was telling all numbers were prime numbers). Today I tried to run the program again and I'm getting a segmentation fault even though I didn't alter my program. I tried using gdb to find when it was happening and I think it's happening on the pthread_join function.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int n_threads; // number of threads
int* numbers; // array of numbers
int elements_per_thread;
int isPrime(int n){
int i = 0;
for(i=0; i < n; i++)
if(n%i == 0)
return 0;
return 1;
}
void * threadPrime(void * arg){
int* idxp = (int*)arg;
int idx = *idxp;
int start = idx* elements_per_thread;
int finish = (idx+1)*elements_per_thread-1;
int i;
for(i=start; i<finish; i++)
if(!isPrime(i))
numbers[i]=0;
pthread_exit(NULL);
}
int main(int argc, char* argv[]) {
if (argc != 3) {
printf("usage: %s largest_number number_threads\n", argv[0]);
return 1;
}
int largest_number = atoi(argv[1]); // value of the largest number to test for primality
int n_numbers = largest_number-1; // number of numbers to test
n_threads = atoi(argv[2]);
// create and fill vector of numbers to test
numbers = (int *)malloc(n_numbers*sizeof(int)) ; // allocate a vector for n_numbers integers
int i;
for (i = 2; i <= largest_number; i++)
numbers[i-2] = i;
int* id = (int *)malloc(n_threads*sizeof(int));
// compute primes
pthread_t* thid = (pthread_t *)malloc(n_threads*sizeof(int));
for(i=0;i<n_threads;i++){
id[i] = i;
if(pthread_create(&thid[i],NULL,threadPrime,(void*)(id+i)) != 0){
printf("Erro\n");
exit(0);
}
}
for(i=0;i<n_threads;i++){
if(pthread_join(thid[i],NULL) != 0){
printf("Erro\n");
exit(0);
}
}
// print result
printf("Primes:");
int n_primes = 0;
for (i = 0; i < n_numbers; i++)
if (numbers[i]) {
n_primes++;
printf (" %d", numbers[i]);
}
printf("\nTotal: %d primes\n", n_primes);
return 0;
}
Problem solved. Correct code below.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int n_threads; // number of threads
int* numbers; // array of numbers
int elements_per_thread;
int isPrime(int n){
int i = 0;
for(i=2; i < n; i++)
if(n%i == 0)
return 0;
return 1;
}
void * threadPrime(void * arg){
int* idxp = (int*) arg;
int idx = *idxp;
int start = idx*elements_per_thread;
int finish = (idx+1)*elements_per_thread;
int i;
for(i=start; i<=finish; i++)
if(!isPrime(numbers[i]))
numbers[i]=0;
pthread_exit(NULL);
}
int main(int argc, char* argv[]) {
if (argc != 3) {
printf("usage: %s largest_number number_threads\n", argv[0]);
return 1;
}
int largest_number = atoi(argv[1]); // value of the largest number to test for primality
int n_numbers = largest_number-1; // number of numbers to test
n_threads = atoi(argv[2]);
// create and fill vector of numbers to test
numbers = (int *)malloc(n_numbers*sizeof(int)) ; // allocate a vector for n_numbers integers
int i;
for (i = 2; i <= largest_number; i++)
numbers[i-2] = i;
int* id;
id = (int *)malloc(n_threads*sizeof(int));
// compute primeselements_per_thread = n_numbers/n_threads;
elements_per_thread = (n_numbers/n_threads)+1;
pthread_t* thid = malloc(n_threads*sizeof(*thid));
for(i=0;i<n_threads;i++){
id[i] = i;
if(pthread_create(&thid[i],NULL,threadPrime,(void*)(id+i)) != 0){
printf("Erro\n");
exit(0);
}
}
for(i=0;i<n_threads;i++){
if(pthread_join(thid[i],NULL) != 0){
printf("Erro\n");
exit(0);
}
}
// print result
printf("Primes:");
int n_primes = 0;
for (i = 0; i < n_numbers; i++)
if (numbers[i]) {
n_primes++;
printf (" %d", numbers[i]);
}
printf("\nTotal: %d primes\n", n_primes);
return 0;
}
There are a number of issues:
1) The starting index for the loop should be 2. Otherwise, you are going to have divide by zero error here:
for(i=0; i < n; i++) // should be i=2
if(n%i == 0)
return 0;
2) elements_per_thread is not set at all. So it's going to be 0 (since it's a global variable) and the loops in thread function will never be called. Set it in main():
elements_per_thread = n_numbers/n_threads;
3) When you call isPrime() you are passing i. But you really wanted to pass numbers[i]. You also want to include the finish in the primality test. So it should be
for(i=start; i<=finish; i++)
if(!isPrime(numbers[i]))
numbers[i]=0;
4) The allocation for thread array is wrong. It should be
pthread_t* thid = malloc(n_threads * sizeof *thid);
There are more efficient ways to test primes (e.g. you only need to check upto n/2 to see if it's prime). But once you fix the above issues, you'll have a working code and think about improving it later.
You didn't allocate the right amount of memory for thid. This is the main reason for your segmentation fault.
pthread_t* thid = (pthread_t *)malloc(n_threads*sizeof(int));
should be
pthread_t* thid = malloc(n_threads*sizeof(p_thread));
(you don't need to cast malloc in C)
This is why I don't usually use an explicit type as the operand of sizeof, and instead just use the variable name so that the compiler can deduce the type itself.
pthread_t* thid = malloc(n_threads*sizeof(*thid));