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.
Related
I want to Interpret how to reach this output for at least 5 different outputs.
And Modify the program to fix this problem.How Can I do it?
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 4
void *threadFunc(void *pArg)
{
int *p = (int*)pArg;
int myNum = *p;
printf("Thread number %d\n", myNum);
return 0;
}
int main(void)
{
int i;
pthread_t tid [NUM_THREADS];
for(i = 0; i < NUM_THREADS; i++)
{
pthread_create(&tid[i], NULL, threadFunc, &i);
}
for(i = 0; i < NUM_THREADS; i++)
{
pthread_join(tid [i], NULL);
}
return 0;
}
Thread function receives pointer to int. Memory it points to is shared between threads, so while thread function reads value of i it is changed by main thread. This is race condition.
You can fix it by storing individual i values for each thread:
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 4
void *threadFunc(void *pArg)
{
int *p = (int*)pArg;
int myNum = *p;
printf("Thread number %d\n", myNum);
return NULL; // thread function returns a pointer
}
int main(void)
{
int i;
pthread_t tid[NUM_THREADS];
int data[NUM_THREADS];
for (i = 0; i < NUM_THREADS; i++)
{
data[i] = i;
pthread_create(&tid[i], NULL, threadFunc, data+i); // `data+i` is equivalent to `&data[i]`
}
for (i = 0; i < NUM_THREADS; i++)
{
pthread_join(tid [i], NULL);
}
return 0;
}
Another option is to pass an integer as a pointer value. It doesn't require storage for each thread but may cause truncating problems because of int<->intptr_t conversion.
#include <stdio.h>
#include <pthread.h>
#include <inttypes.h> // for intptr_t
#define NUM_THREADS 4
void *threadFunc(void *arg)
{
int myNum = (intptr_t)arg;
printf("Thread number %d\n", myNum);
return NULL; // thread function returns a pointer
}
int main(void)
{
int i;
pthread_t tid[NUM_THREADS];
for (i = 0; i < NUM_THREADS; i++)
{
pthread_create(&tid[i], NULL, threadFunc, (void *)(intptr_t)i);
}
for (i = 0; i < NUM_THREADS; i++)
{
pthread_join(tid [i], NULL);
}
return 0;
}
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);
}
#include <stdio.h>
#include <pthread.h>
void *runner(void * p)
{
int *line = p;
printf("line: %d\n", *line);
}
int main()
{
pthread_t tid[2];
for (int i = 0; i < 2; i++)
pthread_create(&tid[i], 0, runner, &i);
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
For the above code I expect the output to be
line 0
line 1
But the output is actually
line 1
line 2
So what is wrong with this code? How did i get incremented? Do I have to pass structs to the runner function?
There's no guarantee that printf("line: %d\n", *line); line will finish before pthread_create returns, which means you have a race on i.
(The main thread tries to increment it and the new threads try to read it
via their argument pointer).
You can solve the problem by passing pointers to different objects (one per thread, optimally cache-aligned, but that hardly matters here):
#include <stdio.h>
#include <pthread.h>
void *runner(void * p)
{
int *line = p;
printf("line: %d\n", *line);
return 0;
}
int main()
{
pthread_t tid[2];
int ints[2];
for (int i = 0; i < 2; i++){
ints[i]=i;
if(pthread_create(&tid[i], 0, runner, &ints[i])) return 1;
}
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
or by passing the i by value (by casting it to void*):
#include <stdio.h>
#include <pthread.h>
#include <stdint.h>
void *runner(void * p)
{
printf("line: %d\n", (int)(intptr_t)p);
return 0;
}
int main()
{
pthread_t tid[2];
int ints[2];
for (int i = 0; i < 2; i++){
if(pthread_create(&tid[i], 0, runner, (void*)(intptr_t)i)) return 1;
}
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
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 got a project from my university for critical section problem of n processes. I have made a code for 2 processes in c But I could not figure out how to get it working for n process . The code is in C for linux threads.
Here is code for 2 Processes.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
int flag[2];
int turn;
const int MAX = 1e9;
int ans = 0;
void lock_init(){
flag[0]=flag[1]=0;
turn = 0;
}
void lock(int self){
flag[self]=1;
turn = 1-self;
while(flag[1-self]==1 && turn == 1-self);
}
void unlock(int self){
flag[self]=0;
}
void* func(void *s){
int i=0;
int *limitptr = (int*) s;
int self = *limitptr;
printf("Thread %d in queue for critical section\n",self);
lock(self);
printf("Thread %d in critical section\n",self);
for(i=0;i<MAX;i++){
ans++;
}
printf("Thread %d done counting\n",self);
printf("Thread %d is exiting critical section\n",self);
unlock(self);
}
int main(){
pthread_t p1, p2;
int a=0,b=1;
lock_init();
pthread_create(&p1, NULL, func, &a);
pthread_create(&p2, NULL, func, &b);
pthread_join(p1, NULL);
pthread_join(p2, NULL);
printf("Exiting Main\n");
return 0;
}
Any help would be appreciated.
Thank You. :)
use a mutex
#include <pthread.h>
declare the mutex like so:
pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;
then at the beginning of a critical section call:
pthread_mutex_lock( &myMutex );
and at the end of the critical section call:
pthread_mutex_unlock( &myMutex );
it does not matter how many threads are using that critical section, only one thread will be able to access it at a time
Thank You for your valuable time and answers.
I Found A solution for My problem and thought of sharing it.I Implemented Bakery Algorithm In C.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
int N;
int global = 10;
int entering[100];
int number[100];
int max(int number[100]) {
int i = 0;
int maximum = number[0];
for (i = 0; i < N; i++) {
if (maximum < number[i])
maximum = number[i];
}
return maximum;
}
void lock(int i) {
int j = 0;
entering[i] = TRUE;
number[i] = 1 + max(number);
entering[i] = FALSE;
for (j = 0; j < N; j++) {
while (entering[j]);
while (number[j] != 0 && (number[j] < number[i] || (number[i] == number[j]) && j < i)) {}
}
}
void unlock(int i) {
number[i] = 0;
}
void *fn(void *integer) {
int i = (int) integer;
lock(i);
printf("\n\n-----------Process %d---------",i);
printf("\nProcess %d is Entering Critical Section\n",i);
global++;
printf("%d is the value of global \n",global);
printf("Process %d is leaving Critical Section\n",i);
printf("----------------------------------\n\n");
unlock(i);
}
int main()
{
printf("Enter Number of Process\n");
scanf("%d",&N);
int th[N];
void *fn(void *);
pthread_t thread[N];
int i = 0;
for (i = 0; i < N; i++) {
th[i] = pthread_create(&thread[i], NULL, fn, (void *)i);
pthread_join(thread[i], NULL);
}
return EXIT_SUCCESS;
}
Again Thank You :)