Real time task (periodic task) - c

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;
}

Related

My code spent long time when I use mutex_lock inside loop

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?

How to synchronize 2 pthreads using mutexes and/or cond vars to create a "guess the number" minigame?

I am trying to make a "guess the number" minigame to get used to pthreads and synchronization. A thread sleeps for 10 seconds, while the other reads input and says whether the number is too big or too low. When the first thread "wakes up", the second thread should no longer read input, regardless if it were executing scanf. When the second thread has read the correct number, the first thread should no longer sleep and ignore the rest of its code.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
unsigned short quit = 0;
unsigned short won = 0;
void * engine(void * arg);
void * arbiter();
int main(int argc, char** argv) {
int n = rand() % 100;
pthread_t t1, t2;
pthread_create(&t1, NULL, arbiter, NULL);
pthread_create(&t2, NULL, engine, &n);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return (EXIT_SUCCESS);
}
void * arbiter(){
sleep(10);
quit = 1;
printf("Stop!\n");
}
void * engine(void * arg){
int n = *(int*)arg;
printf("%d\n", n);
while(!quit){
printf("N = ");
int a;
scanf("%d", &a);
if(a < n){
printf("Go higher!\n");
} else if(a > n){
printf("Go lower!\n");
} else{
printf("Bingo!\n");
won = 1;
}
}
}
I don't know how to use mutexes or cond var here, to make the threads work together. Now, when the first thread wakes up, the second will execute the last scanf. How should I implement this correctly and safe?

segmentation fault in multithread program

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.

Issue creating multiple threads with pthreads

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void *compute() {
float total;
int i;
float oldtotal =0, result =0;
for(i=0;i<1999999999;i++)
{
result =sqrt(1001.0)*sqrt(1001.0);
}
printf ("Result is %f\n", result);
oldtotal = total;
total = oldtotal + result;
printf("Total is %f\n",total);
return NULL;
}
int main() {
pthread_t thread1, thread2;
pthread_create(&thread1, NULL,compute, NULL);
pthread_create(&thread2, NULL,compute, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}
Only one thread is created when I run the program. I've checked this using the top command in cmd, the process runs at 197% so I believe two processes are being run. I've remembered to compile it with the -pthreads flag.
197% = 2 threads exercising the cpu doing sqrt() in a loop, plus one thread which is not using any cpu because it is waiting for the other threads to finish in pthread_join().

pthread_join function kill the thread after execution or we need to call pthread_cancel/pthread_exit?

pthread_join() function kill the thread after execution or we need to call pthread_cancel()/pthread_exit()?
I am calling pthread_cancel()/pthread_kill() which is returning 3 ie no thread attached with thread_id.
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
void * run (void *);
int main() {
pthread_t p1, p2;
int a = 9;
printf("%d\n", pthread_create(&p1, NULL, &run, (void*)&p1));
printf("%d\n", pthread_create(&p2, NULL, &run, (void*)&p2));
printf("%d\n", pthread_join(p1, NULL));
//usleep(1000);
printf("%d\n", pthread_join(p2, NULL));
printf("before exit\n");
printf("%d\n", pthread_cancel(p1));
printf("after exit\n");
printf("%d\n", pthread_cancel(p2));
printf("both thread exited\n");
printf("%d\n", pthread_join(p1, NULL));
printf("%d\n", pthread_join(p2, NULL));
printf("terminated\n");
printf("%d\n", pthread_kill(p1, 0));
printf("%d\n", pthread_kill(p2, 0));
printf("ext\n");
printf("%d\n", pthread_join(p1, NULL));
printf("%d\n", pthread_join(p2, NULL));
printf("jion\n");
return 0;
}
void *run (void *p) {
int *i = (int*)p;
printf("created i = %d\n", *i);
}
This is the code i am using. in this pthread_cancel on wards all function returning 3 which means thread is being already killed.
pthread_join does not kill the thread, it waits for the thread to complete. If you want to kill a thread then use pthread_kill. But that has to be done before pthread_join, otherwise the thread has already exited.
pthread_cancel requests that the thread teminate at the next cancellation point, and is probably safer than using pthread_kill.
pthread_exit exits the current thread.
Some context would be nice... but if you're just waiting for a thread (presumably you only have one you care about) to terminate/return, then pthread_join is good enough.
The pthread_join() function waits for the thread specified by thread
to terminate. If that thread has already terminated, then pthread_join() returns
immediately.
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_join.3.html
Check the man page for usage/warnings.
After pthread_join() Add
/* Last thing that main() should do */
pthread_exit(NULL);
For more details pls refer here.
pthread_join() is used to make the main() thread wait till all the threads completes it's execution. Control reaches the pthread_join(), when that particular thread completes it's execution.
So if you try to cancel/kill that particular thread, error will be returned.
Sample Code
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 4
void *BusyWork(void *t)
{
int i;
long tid;
tid = (long)t;
printf("Thread %ld starting...\n",tid);
pthread_exit((void*) t); //Exits that current thread.
}
int main (int argc, char *argv[])
{
pthread_t thread[NUM_THREADS];
int rc;
long t;
void *status;
for(t=0; t<NUM_THREADS; t++) {
printf("Main: creating thread %ld\n", t);
rc = pthread_create(&thread[t], NULL, BusyWork, (void *)t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Wait for completion */
for(t=0; t<NUM_THREADS; t++) {
rc = pthread_join(thread[t], &status);
if (rc) {
printf("ERROR; return code from pthread_join() is %d\n", rc);
exit(-1);
}
printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status);
}
printf("Main: program completed. Exiting.\n");
pthread_exit(NULL); // Exits main thread.
}
For #Joachim Pileborg
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 4
void *BusyWork(void *t)
{
int i;
long tid;
tid = (long)t;
printf("Thread %ld starting...\n",tid);
for(i = 0; i <10000000; i++)
printf("\n Thread: %ld, %d", tid, i);
pthread_exit((void*) t); //Exits that current thread.
}
int main (int argc, char *argv[])
{
pthread_t thread[NUM_THREADS];
int rc;
long t;
void *status;
for(t=0; t<NUM_THREADS; t++) {
printf("Main: creating thread %ld\n", t);
rc = pthread_create(&thread[t], NULL, BusyWork, (void *)t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
//printf("Main: program completed. Exiting.\n");
pthread_exit(NULL); // Exits main thread(work will be done).
//return 0;//( Threads will exit once main exits.)
}

Resources