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.
Related
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.
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 have two functions, producer and consumer called by two p threads, but the while loop in the function is not running. Its a linux RT system. this is my code. im coding in eclipse.
#include <stdio.h>
#include"NIDAQmx.h"
#include <pthread.h>
#include "sts_queue/s_q.c"
#include <stdlib.h>
void *producer(void *ptr);// first function
void *consumer(void *ptr);// second function
TaskHandle taskHandle = 0;
int ret = 0;
int numChannels = 0;
int numRead;
float64 data[100];
int iret1, iret2;
pthread_t thread1, thread2;
int main(void) {
char *message1 = "Producer ended";
char *message2 = "consumer ended";
init();
ret = DAQmxCreateTask("task", &taskHandle);
ret=DAQmxCreateAIVoltageChan(taskHandle, "PXI1Slot2/ai0", "",
DAQmx_Val_Cfg_Default, -5, 5, DAQmx_Val_Volts, NULL);
ret=DAQmxCfgSampClkTiming(taskHandle, "", 1000, DAQmx_Val_Rising,DAQmx_Val_ContSamps, 100);
ret=DAQmxGetTaskAttribute(taskHandle, DAQmx_Task_NumChans, &numChannels);
ret=DAQmxStartTask(taskHandle);
iret1 = pthread_create(&thread1, NULL, producer,(void*) message1);// calling two threads
iret2 = pthread_create(&thread2, NULL, consumer,(void*) message2);// calling thread
}
void *producer(void *ptr) // enque function
{
char *message;
int i = 0;
int ret;
message = (char *) ptr;
while(i<1000)
{
//ret=DAQmxReadAnalogF64(taskHandle, 100, 10.0, DAQmx_Val_GroupByChannel, data,100 * numChannels, &numRead, NULL);
printf("task handle=%d\n",taskHandle);
printf("value of i=%d\n",i);
printf("Number of sample read%d\n",numRead);
printf("ret%d\n",ret);
sleep(.1);
i++;
}
ret=DAQmxStopTask(taskHandle);
ret=DAQmxClearTask(taskHandle);
printf("%s \n", message);
pthread_join(thread1, NULL);
return 0;
}
void *consumer(void *ptr) // deque function
{
char *message;
int k = 0;
int elements=0;
message = (char *) ptr;
while(k<1000)
{
printf("value ofk=%d\n",k);
sleep(.1);
k++;
}
printf("%s \n", message);
pthread_join(thread2, NULL);
}
Should i use pthread_exit or pthread-join?
how to use pthead_exit to exit first thread when while loop has exited?
now my console prints just this
task handle=-163491360
start0
value ofk=0
task handle=-163491360
value of i=0
Number of sample read0
ret0
logout
but actually value of i and k should go to 1000 and when it reaches 1000, while loop will stop and exit
Sometimes im getting this error too
pure virtual method called
terminate called without an active exception
Aborted
logout
You need to call pthread_join in the main function after creating thread1 and thread2. Otherwise, the main thread will terminate before thread1 and thread2 are completed.
Good evening everyone,
I'm still learning real-time programming, and I'm trying to synchronize two threads using semaphores, the first thread calculates the sum and returns a value (sum). the sum will be passed as a parameter to the 2nd thread that will use it to calculate an average (this is just an example for manipulating semaphores). my problem now and that the two tasks are not periodic because once the thread returns a result it leaves the loop while and the main() finishes the work !!! now how to make the tasks period ?? thank you for helping me and here is my source code.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
sem_t evt;
//first task
void *tache1(void *arg)
{
int j;
int s=0;
struct timespec time;
clock_gettime(CLOCK_REALTIME, &time);
while(1){
printf("first THREADDDDDDDDD \n");
for(j=0; j<100; j++)
s= s + j;
return (void*) s;
sem_post(&evt);
sleep(3);
}
}
//second task
void *tache2(void *arg){
int moyenne = 1;
int sum = *((int*) arg);
struct timespec time;
clock_gettime(CLOCK_REALTIME, &time);
while(3){
sem_wait(&evt);
printf("second THREADDDDDDDDD \n");
moyenne= sum/10;
return(void*)moyenne;
sleep(2);
}
}
int main()
{
pthread_t th1, th2;
int sum;
int moyenne;
int status;
sem_init(&evt, 0,0);
printf("start main\n") ;
pthread_create(&th1, NULL, tache1, NULL);
pthread_join(th1, (void*) &sum);
pthread_create(&th2, NULL, tache2, &sum);
pthread_join(th2, (void*) &moyenne);
printf("the sum in the main is %d.\n", sum);
printf("AVG %d.\n", moyenne);
printf("End main\n") ;
return 0;
}
When you do this:
pthread_create(&th1, NULL, tache1, NULL);
pthread_join(th1, (void*) &sum);
pthread_create(&th2, NULL, tache2, &sum);
pthread_join(th2, (void*) &moyenne);
You start a thread, wait for it to finish, then start another thread, then wait for that to finish. That's not multithreading. You want both threads to be active at the same time.
Also, both of your thread functions include a return statement with more statements after them. Once a return statement is hit, the entire function returns immediately. No statements after them are executed. Note also that you don't need a while (1) (or while (3)) loop in either of these functions.
The idea behind semaphores (and mutexes) is that multiple threads are running at once, and both thread need to operate on global data so one thread needs to wait for the other thread to do something before it can access the global data.
So make sum and moyenne global variables, start both threads at once, and get rid of the extra loops in the thread functions.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
sem_t evt;
int sum;
int moyenne;
void *tache1(void *arg)
{
int j;
int s=0;
printf("first THREADDDDDDDDD \n");
for(j=0; j<100; j++)
s= s + j;
sum = s;
sem_post(&evt);
return NULL;
}
void *tache2(void *arg)
{
sem_wait(&evt);
printf("second THREADDDDDDDDD \n");
moyenne= sum/10;
return NULL;
}
int main()
{
pthread_t th1, th2;
sem_init(&evt, 0,0);
printf("start main\n") ;
pthread_create(&th1, NULL, tache1, NULL);
pthread_create(&th2, NULL, tache2, NULL);
pthread_join(th1, NULL);
pthread_join(th2, NULL);
printf("the sum in the main is %d.\n", sum);
printf("AVG %d.\n", moyenne);
printf("End main\n") ;
return 0;
}
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;
}