I'm trying to implement a mutex lock example code, but it doesn't work as well as the theory of mutex lock.
I create 10 threads for my program, 9 threads are reading an array and one thread change the array. In the theory of lock, if I lock the array before changing it then other threads can not read it.
but my program runs differently. please check the code below and help me to understand where to call pthread mutex lock functions:
// C program to generate random numbers
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#define NUM_THREADS 10
pthread_mutex_t lock;
int array[1000] = {0};
pthread_t threads[NUM_THREADS];
int change_array(int *array)
{
int arrayhelper[1000] = {0};
for (int i = 0; i < 1000; ++i)
arrayhelper[i] = i;
pthread_mutex_lock(&lock);
for (int i = 0; i < 1000; ++i)
array[i] = 0;
for (int i = 0; i < 1000; ++i)
array[i] = arrayhelper[i];
pthread_mutex_unlock(&lock);
return 1;
}
void *read_array(){
while(1)
if (array[10] == 0)
printf("%d failed to lock!\n", array[10]);
}
void *write_array(){
while(1)
{
sleep(1);
change_array(array);
}
}
int main (){
pthread_mutex_init(&lock, NULL);
for (int i = 0; i < 1000; ++i)
array[i] = i;
pthread_create(&threads[0], NULL, *write_array, NULL);
pthread_create(&threads[1], NULL, *read_array, NULL);
pthread_create(&threads[2], NULL, *read_array, NULL);
pthread_create(&threads[3], NULL, *read_array, NULL);
pthread_create(&threads[4], NULL, *read_array, NULL);
pthread_create(&threads[5], NULL, *read_array, NULL);
pthread_create(&threads[6], NULL, *read_array, NULL);
pthread_create(&threads[7], NULL, *read_array, NULL);
pthread_create(&threads[8], NULL, *read_array, NULL);
pthread_create(&threads[9], NULL, *read_array, NULL);
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
pthread_join(threads[2], NULL);
pthread_join(threads[3], NULL);
pthread_join(threads[4], NULL);
pthread_join(threads[5], NULL);
pthread_join(threads[6], NULL);
pthread_join(threads[7], NULL);
pthread_join(threads[8], NULL);
pthread_join(threads[9], NULL);
pthread_mutex_destroy(&lock);
pthread_exit(NULL);
return 1;
}
Theoretically, when you run this code, the read_array function should not print anything but in a moment array elements will be 0 and other threads achieve that.
Related
I tried to make a parallel program that generates a random number with one thread and the other thread writes it.
Am I doing something wrong that messes with the performance/optimization? I ask it because it was very easy to write this program so I'm a little concerned that I am doing something wrong.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#include "produceConsume.h"
#define NUM_THREAD 1
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int queue[1];
int queueCounter = 0;
void *producer(void *args)
{
while (1)
{
pthread_mutex_lock(&lock);
int n = rand() % 100;
queue[queueCounter] = n;
queueCounter++;
pthread_cond_wait(&cond, &lock);
pthread_mutex_unlock(&lock);
}
}
void *consumer(void *args)
{
while (1)
{
pthread_mutex_lock(&lock);
printf("%d\n", queue[queueCounter - 1]);
queueCounter--;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
sleep(1);
}
}
int main()
{
system("clear");
srand(time(NULL));
pthread_t th[NUM_THREAD], th2[NUM_THREAD];
for (int i = 0; i < NUM_THREAD; i++)
{
pthread_create(&th[i], NULL, &producer, NULL);
pthread_create(&th2[i], NULL, &consumer, NULL);
}
for (int i = 0; i < NUM_THREAD; i++)
{
pthread_join(th[i], NULL);
pthread_join(th2[i], NULL);
}
}
You don't need an array if you are going to use only one thread, in any case, you create two threads but only one is joined (leaking memory), instead:
pthread_t th1[NUM_THREAD]; // or simply pthread_t th1;
pthread_t th2[NUM_THREAD]; // or simply pthread_t th2;
for (int i = 0; i < NUM_THREAD; i++)
{
pthread_create(&th1[i], NULL, &producer, NULL);
pthread_create(&th2[i], NULL, &consumer, NULL);
}
for (int i = 0; i < NUM_THREAD; i++)
{
pthread_join(th1[i], NULL);
pthread_join(th2[i], NULL);
}
When I use mutex_lock inside loop, my code spends huge time in execution, and I can't get the output.
I know lock () take time, but not as this!
I have this code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int x = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *fnC()
{
int i;
for (i = 0; i < 2; i++)
{
pthread_mutex_lock(&mutex);
x++;
}
printf(" %d", x);
pthread_mutex_unlock(&mutex);
}
int main()
{
int rt1, rt2;
pthread_t t1, t2;
/* Create two threads */
if ((rt1 = pthread_create(&t1, NULL, &fnC, NULL)))
printf("Thread creation failed: %d\n", rt1);
if ((rt2 = pthread_create(&t2, NULL, &fnC, NULL)))
printf("Thread creation failed: %d\n", rt2);
/* Wait for both threads to finish */
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("\n");
return 0;
}
Anyone can explain this?
I'm trying to write a program that uses 3 threads with a shared memory. the shared memory is an array with 101 values. the first value shared memory[0](initialized to 0) is status value which determines which operation should take place. the three threads do
The first one should fill the shared memory array with 100 random values. and set the status value to 1.
The second should print the product of the 100 random values (from index 1 to 100). and set the status value to 2.
The third should print the average of the 100 random variables. and set the status value to 0. so that thread one fill the shared memory with different random variables.
this is my code
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
unsigned int product=0;
float avg=0;
int* shared_memory;
int status=0;
void productAllThread();
void averageAllThread();
void *parentProcess();
void *prodAll();
void *avgAll();
void initializeArray();
int main(int argc, const char * argv[])
{
time_t t;
key_t key = 9876;
// Create shared memory area
int shm_id = shmget(key, sizeof(int)*101, IPC_CREAT | 0666);
// initialize the random variable
srand((unsigned) time(&t));
// Create shared memory
shared_memory=shmat(shm_id, NULL, 0);
//create threads
pthread_t tid1, tid2, tid3;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid1, &attr, parentProcess, NULL);
pthread_create(&tid2, &attr, prodAll, NULL);
pthread_create(&tid3, &attr, avgAll, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_join(tid3, NULL);
return 0;
}
void initializeArray() {
shared_memory[0]=0;
status=shared_memory[0];
int i= 0;
printf("Initial Array:{");
for(i=1; i<100; i++)
{
shared_memory[i]=rand()% 50;
printf("%d,", shared_memory[i]);
}
printf("}\n");
}
void *parentProcess()
{
while(1)
{
status=shared_memory[0];
if(status==0) {
// initialize array
initializeArray();
shared_memory[0]=1;
} else {
sleep(10);
}
}
}
void averageAllThread() {
while(1) {
status=shared_memory[0];
if(status==2)
{
avgAll();
wait(NULL);
printf("Avg:%.2f\n", avg);
shared_memory[0]=0;
} else {
sleep(5);
}
}
}
void productAllThread() {
while(1){
status=shared_memory[10];
if (status==1)
{
prodAll();
wait(NULL);
printf("Sum:%d\n",product);
shared_memory[0]=2;
} else {
sleep(5);
}
}
}
void *prodAll()
{
while(1){
int i=1;
product=0;
for(i=1; i<100; i++)
{
product=product+shared_memory[i];
}
}
}
void *avgAll()
{
while(1){
int i=0;
avg=0;
for(i=1; i<100; i++)
{
avg=avg+shared_memory[i];
}
avg=avg/100;
}
}
when I run it in the terminal, it gives me this error
"Segmentation fault: 11"
what might cause this type of errors? If this error is fixed will the program work fine to do the job I want it to do?
I found a few problems in your program:
You are calling the wrong functions to start your threads:
pthread_create(&tid1, &attr, parentProcess, NULL);
pthread_create(&tid2, &attr, prodAll, NULL);
pthread_create(&tid3, &attr, avgAll, NULL);
Should be:
pthread_create(&tid1, &attr, parentProcess, NULL);
pthread_create(&tid2, &attr, productAllThread, NULL);
pthread_create(&tid3, &attr, averageAllThread, NULL);
You have a few calls to wait() like this:
wait(NULL);
You should remove all of them.
The while loops in avgAll() and prodAll() should be removed since there are already while loops in the callers of those functions.
The call to srand() should be made from parentProcess() otherwise it might not affect the rand() calls in that thread.
// This is the multi-threaded code for a producer Consumer program ,it runs //successfully completion of both the threads , but receives a Segmentation error just //before thread join , I am not really able to figure it out
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
void* writer_function ();
void* reader_function ();
char buffer[9];
sem_t empty_buffers;
sem_t full_buffers;
int main()
{
pthread_t thread1, thread2;
//const char *message1 = "Thread 1";
//const char *message2 = "Thread 2";
int iret1, iret2;
sem_init(&empty_buffers,0,8);
sem_init(&full_buffers,0,0);
/* Create independent threads each of which will execute function */
iret1 = pthread_create( &thread1, NULL,writer_function, NULL);
if(iret1)
{
fprintf(stderr,"Error - pthread_create() return code: %d\n",iret1);
exit(EXIT_FAILURE);
}
iret2 = pthread_create( &thread2, NULL, reader_function(), NULL);
if(iret2)
{
fprintf(stderr,"Error - pthread_create() return code: %d\n",iret2);
exit(EXIT_FAILURE);
}
// Runs Successfully ,and segmentation fault here
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
printf("pthread_create() for thread 1 returns: %d\n",iret1);
printf("pthread_create() for thread 2 returns: %d\n",iret2);
sem_destroy(&empty_buffers);
sem_destroy(&full_buffers);
/* Wait till threads are complete before main continues. Unless we */
/* wait we run the risk of executing an exit which will terminate */
/* the process and all threads before the threads have completed. */
printf("This marks the end and the threads to be joined \n ");
//exit(EXIT_SUCCESS);
return 0;
}
void* writer_function ()
{
int i ;
for (i = 0 ; i < 40 ; i++){
char c = (i + 66);
sem_wait(&empty_buffers);
buffer[i%8] = c;
sem_post(&full_buffers);
printf(" WRITER:the letter Written is %c\n", c);
}
}
void* reader_function ()
{
int i ;
for (i = 0 ; i < 40 ; i++){
sem_wait(&full_buffers);
char c = buffer[i%8];
sem_post(&empty_buffers);
printf("READER:the letter Received is %c\n", c);
}
}
change:
iret2 = pthread_create( &thread2, NULL, reader_function(), NULL);
to
iret2 = pthread_create( &thread2, NULL, reader_function, NULL);
add return NULL; for both functions reader_function, writer_function after loop and change their header from writer_/reader_function() to writer_/reader_function(void *args)
I have a big problem, I can't figure out why mutexes in C don't work as I expect.
This is my code:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
pthread_t mythread;
pthread_mutex_t mymutex;
void *anotherFunc(void*)
{
pthread_mutex_lock(&mymutex);
for(int i = 0; i < 100; i++)
printf("anotherFunc\n");
pthread_mutex_unlock(&mymutex);
pthread_exit(NULL);
}
void *func(void*)
{
pthread_mutex_lock(&mymutex);
for(int i = 0; i < 100; i++)
printf("func\n");
pthread_mutex_unlock(&mymutex);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_mutex_init(&mymutex, NULL);
pthread_create(&mythread, NULL, func, NULL);
pthread_create(&mythread, NULL, anotherFunc, NULL);
pthread_mutex_destroy(&mymutex);
pthread_exit(NULL);
return EXIT_SUCCESS;
}
What I expect to happen is the program to print first 100 "func" messages and then 100 "anotherFunc" messages. What I expect is execution to reach func and lock the mutex. When the execution reaches anotherFunc, I expect to wait until func unlocks the mutex. But I get interfered messages like
func
func
func
anotherFunc
anotherFunc
anotherFunc
func
anotherFunc
I don't understand how this thing works. Please help!
pthread_create(&mythread, NULL, func, NULL);
pthread_create(&mythread, NULL, anotherFunc, NULL);
pthread_mutex_destroy(&mymutex);
You're destroying the mutex before the threads are done with it, so all bets are off. You'll probably want to pthread_join the 2 threads before destroying it.
I got few comiplation errors
I couldn't declare int i in for loop
Used an argument name arg as an argument for threads "func" and "anotherFunc"
I have used pthread_join before destroying the mutex.
In this way I am destroying my mutex "mymutex" after both threads "func" and "anotherFunc" have completed their execution
Also each threads now has their own thread id "mythread1" and "mythread2" so in this way I can use pthread_join() function for each thread
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
pthread_t mythread1, mythread2;
pthread_mutex_t mymutex;
void *anotherFunc(void *arg)
{
pthread_mutex_lock(&mymutex);
int i;
for(i = 0; i < 100; i++)
printf("anotherFunc\n");
pthread_mutex_unlock(&mymutex);
pthread_exit(NULL);
}
void *func(void *arg)
{
pthread_mutex_lock(&mymutex);
int i;
for(i = 0; i < 100; i++)
printf("func\n");
pthread_mutex_unlock(&mymutex);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_mutex_init(&mymutex, NULL);
pthread_create(&mythread1, NULL, func, NULL);
pthread_create(&mythread2, NULL, anotherFunc, NULL);
pthread_join(mythread1, NULL);
pthread_join(mythread2, NULL);
pthread_mutex_destroy(&mymutex);
return EXIT_SUCCESS;
}