Im try to write program that create 2 threads, that first thread will print all the even numbers from 0 to number and the second thread will print all the odd numbers from 1 to the same number.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void* printOddNumbers(void* maxNumbers);
void* printEvenNumbers(void* maxNumbers);
int main(){
pthread_t oddNumbersThread;
pthread_t evenNumbersThread;
int maxNumber = 20;
pthread_create(&oddNumbersThread, NULL, printOddNumbers, (void *)maxNumber);
pthread_create(&evenNumbersThread, NULL, printEvenNumbers, (void *)maxNumber);
printf("Main thread1 finished");
return 0;
}
void* printOddNumbers(void* maxNumbers){
int *maxNumber = (int *)maxNumber;
int currentNumber = 1;
while(currentNumber <= *maxNumber){
sleep(1);
printf("Odd: %d", currentNumber);
currentNumber += 2;
}
}
void* printEvenNumbers(void* maxNumbers){
int *maxNumber = (int *)maxNumber;
int currentNumber = 0;
while(currentNumber <= *maxNumber){
sleep(1);
printf("Evem: %d", currentNumber);
currentNumber += 2;
}
}
when i run the program, it return Segmentation fault, and i dont undetstand why because im not trying to access any unauthorized memory from inside the threads. Thanks !
Related
I'm trying to write a code that prints "Hello World!" 10 times with "sleep" for a second, then the program should print "Hello Moon!" 10 times with "sleep" for 0.2 seconds. This process must be repeated forever. The problem is that the program only prints "Hello World!" 10 times. I do not really understand how to get the next thread to run!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "wrapper.h"
#include <pthread.h>
#define MAX 10
void* HelloMoonFunction(void* tid){
long t_id;
t_id = (long)tid;
sleep(tid);
printf("%d. Hello Moon! \n", tid+1);
return NULL;
}
void* HelloWorldFunction(void* tid){
int value = (int) (intptr_t) tid;
sleep(value);
printf("%d. Hello World!\n", value + 1);
return NULL;
}
int main(int ac, char * argv){
pthread_t hej,moon;
while(1){
for (int a = 0; a < MAX; a++){
pthread_create(&hej, NULL, HelloWorldFunction, (void*)(intptr_t) a);
}
for (int b = 0; b < MAX; b++){
pthread_join(&hej, NULL);
}
for (int i = 0; i < MAX; i++){
pthread_create(&moon, NULL, HelloMoonFunction, (void*)(intptr_t) i);
}
for (int j = 0; j < MAX; j++){
pthread_join(moon, NULL);
}
}
pthread_exit(NULL);
return(0);
}
The most important issue in your code is that the 10 thread IDs are stored in the same variable so the 10 pthread_joins are all called for the last thread ID.
Secondly, the data passed to the thread functions is an integer encoded into a pointer. This is not guaranteed to go well. A more portable approach would be to save the argument and pass a pointer to the saved value. However, your approach does simplify the code, so I have kept it below. Just be warned.
The 0.2 seconds difference in sleep times that you would like in the HelloMoonFunction() cannot be accomplished with sleep (sleep for n seconds), but the Posix usleep (sleep for n microseconds) is probably available even though it is obsoleted by Posix.
A modified version doing what I understand you want to accomplish could be the following:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define MAX 10
void* HelloMoonFunction(void* tid){
int value = (intptr_t)tid;
usleep(value*200000);
printf("%d. Hello Moon! \n", value+1);
return NULL;
}
void* HelloWorldFunction(void* tid){
int value = (intptr_t)tid;
usleep(value*1000000);
printf("%d. Hello World!\n", value + 1);
return NULL;
}
int main(void){
pthread_t hej[MAX], moon[MAX];
while(1){
for (int a = 0; a < MAX; a++){
pthread_create(&hej[a], NULL, HelloWorldFunction, (void *)(intptr_t)a);
}
for (int b = 0; b < MAX; b++){
pthread_join(hej[b], NULL);
}
for (int i = 0; i < MAX; i++){
pthread_create(&moon[i], NULL, HelloMoonFunction, (void *)(intptr_t)i);
}
for (int j = 0; j < MAX; j++){
pthread_join(moon[j], NULL);
}
}
return(0);
}
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.
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 have a quick question. I'm learning about semaphores and I want only four threads to be able to access someFunction() at any given time. This function needs to execute num_task times. This is what I have so far, but valgrind is throwing some errors saying that I have possible memory leaks. Please tell me where I'm going wrong and how to go about fixing this. Thank you!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#include <semaphore.h>
sem_t s;
typedef struct Data Data;
struct Data {
int index;
int j;
};
void* someFunction(void* arg){
// make sure only four threads access this function at once
sem_wait(&s);
Data* a = arg;
printf("i%d j%d\n", a->index, a->j);
sleep(1);
free(a);
sem_post(&s);
return 0;
}
int main(void){
int num_task = 10; // i need to call someFunction() 9000 times
int num_threads = 4;
sem_init(&s, 0, num_threads);
int j = 0;
pthread_t thread_ids[num_threads];
for (int i = 0; i < num_task; i ++){ // these are our columns
sem_wait(&s);
if (j > num_threads - 1){
j = 0; // j goes 0 1 2 3 0 1 2 3 0 1 2 3 ....
}
Data* a = malloc(sizeof(Data));
a->index = i;
a->j = j;
printf("MAIN j%d\n", j);
pthread_create(thread_ids + j, NULL, someFunction, a);
j ++;
sem_post(&s);
}
for (int i = 0; i < num_threads; i ++){
pthread_join(thread_ids[i], NULL);
}
sem_destroy(&s);
return 0;
}
I am a beginner in C programming and I am trying to perform mutex on the program below, but I'm not getting the proper output.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREAD 4
void *func(void *p);
int counter=0,a=2;
pthread_mutex_t mutexsum = PTHREAD_MUTEX_INITIALIZER;
main()
{
int i,rc;
pthread_t threadid[NUM_THREAD];
for(i = 0; i< NUM_THREAD; i++)
{
a = a + i;
printf("Value of a is %d\n",a);
rc = pthread_create(&threadid[i],NULL,func,(void *)a);
if(rc)
{
printf("Error in thred creation thread[%d] %d",i,rc);
}
}
for(i = 0; i< NUM_THREAD; i++)
{
pthread_join(threadid[i],NULL);
}
printf("Final value of counter is %d\n",counter);
pthread_exit(NULL);
}
void *func(void *p)
{
int i;
i = (int) p;
pthread_mutex_lock(&mutexsum);
counter = counter+a;
printf("%d\n",counter);
pthread_mutex_unlock(&mutexsum);
pthread_exit(NULL);
}
As per the above program and my understanding, the desired output will be 18, but it's giving 32.
func uses a to increment. I'm guessing you meant to increment by i. As it is, by the time each thread runs, a must be at its final value of 8, so you are adding 8 to counter four times.
You are not using i in your thread function, but a.