I am a student and i encountered a following task using multithreading in c, the problem is I am trying to protect shared variable cnt using P and V operataions. I am using semaphore to protect the shared variable, but it is giving me following errors:
correctcntn.c:15:10: error: expected declaration specifiers or ‘...’ before ‘&’ token
sem_init(&mutex, 0, 1);
^
correctcntn.c:15:18: error: expected declaration specifiers or ‘...’ before numeric constant
sem_init(&mutex, 0, 1);
^
correctcntn.c:15:21: error: expected declaration specifiers or ‘...’ before numeric constant
sem_init(&mutex, 0, 1);
Thank you in advance! Any help is appreciated!
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include<semaphore.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
void *thread(void *vargp);
volatile long cnt = 0;
sem_t mutex;
sem_init(&mutex, 0, 1);
void P(sem_t *s)
{
sem_wait(&s);
}
void V(sem_t *s)
{
sem_post(&s);
}
int main(int argc, char **argv)
{
long niters;
pthread_t tid1, tid2;
niters = atoi(argv[1]);
pthread_create(&tid1, NULL, thread, &niters);
printf("THREAD 1 with tid= %ld CREATED \n", tid1);
pthread_create(&tid2, NULL, thread, &niters);
printf("THREAD 2 with tid= %ld CREATED \n", tid2);
pthread_join(tid1, NULL);
printf("THREAD 1 with tid= %ld TERMINATED \n", tid1);
pthread_join(tid2, NULL);
printf("THREAD 2 with tid= %ld TERMINATED \n", tid2);
if (cnt != (2 * niters))
printf("BOOM! cnt=%ld\n", cnt);
else
printf("OK cnt=%ld\n", cnt);
exit(0);
}
void *thread(void *vargp)
{
long i, niters = *((long *)vargp);
for (i = 0; i < niters; i++)
P(&mutex);
cnt++;
V(&mutex);
return NULL;
}
Statements to be executed like sem_init(&mutex, 0, 1); must be in function bodies in C.
You should move that inside a function body -- for example, at the beginning of the main() function.
int main(int argc, char **argv)
{
long niters;
pthread_t tid1, tid2;
sem_init(&mutex, 0, 1); /* move to here */
niters = atoi(argv[1]);
Related
This is my current code for the Producer-Consumer problem. I compiled it and ran it but nothing is printed. The command line takes in 3 arguments: Sleep time, producer threads, consumer threads. I've tried setting the values as 5, 1, 1 respectively, the sleep timer works but I'm unsure about the rest.
Code for buffer.h:
typedef int buffer_item;
#define BUFFER_SIZE 5
Code for buffer.c:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include "buffer.h"
buffer_item buffer[BUFFER_SIZE];
void *producer(void *param);
void *consumer(void *param);
pthread_mutex_t mutex;
sem_t empty;
sem_t full;
int insert_item(buffer_item item)
{
do
{
wait(empty);
wait(mutex);
signal(mutex);
signal(full);
}while(1);
return 0;
}
int remove_item(buffer_item *item)
{
do
{
wait(full);
wait(mutex);
signal(mutex);
signal(empty);
}while(1);
return 0;
}
int main(int argc, char *argv[])
{
int sleepTime;
int producerThreads;
int consumerThreads;
int counter_1;
int counter_2;
if(argc != 4)
{
return -1;
}
sleepTime = atoi(argv[1]);
producerThreads = atoi(argv[2]);
consumerThreads = atoi(argv[3]);
srand((unsigned)time(NULL));
for(counter_1 = 0; counter_1 < producerThreads; counter_1++)
{
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid, &attr, producer, NULL);
}
for(counter_2 = 0; counter_2 < consumerThreads; counter_2++)
{
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid, &attr, consumer, NULL);
}
sleep(sleepTime);
return 0;
}
void *producer(void *param)
{
buffer_item item;
int randomTime;
int counter_1 = 0;
while(1)
{
randomTime = rand() % 1000 + 1;
sleep(randomTime);
item = rand();
if(insert_item(item))
{
fprintf(stderr, "Error.");
}
else
{
printf("Producer ID: %lu, Produced Item: %d\n", pthread_self(), item);
printf("The buffer now contains %d items\n", counter_1);
++counter_1;
}
}
}
void *consumer(void *param)
{
buffer_item item;
int randomTime;
int counter_2 = 0;
while(1)
{
randomTime = rand() % 1000 + 1;
sleep(randomTime);
if(insert_item(item))
{
fprintf(stderr, "Error.");
}
else
{
printf("Consumer ID: %lu, Consumed Item: %d\n", pthread_self(), item);
printf("The buffer now contains %d items\n", counter_2);
++counter_2;
}
}
}
So far I've tried declaring the tid separately, skipping sleep and join the threads, but it still doesn't print.
Your code can't possibly run, indeed it doesn't even compile.
Here's a list of issues that need to be addressed:
wait should be sem_wait
signal should be sem_post for semaphores
int sem_wait(sem_t *sem); and int sem_post(sem_t *sem); take the pointer to a semaphore
sem_wait(mutex) and sem_post(mutex) give something like "incompatible type for argument 1 of sem_wait", I guess you want to acquire and release the lock on the mutex like pthread_mutex_lock(&mutex) and pthread_mutex_unlock(&mutex)
in the consumer if(insert_item(item)): item is used uninitialized
still in the consumer you use insert_item instead of remove_item
Coming to the main question "I compiled it and ran it but nothing is printed", it doesn't print anything because producer and consumer call, respectively, insert_item and remove_item and are trapped inside infinite loops (e.g. while(1))
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.
int pthread_create(pthread_t *thread,const pthread_attr_t *attr, void*(*start_routine) (void *), void *arg);
void *thread(void *vargp);
/* Global shared variable */
volatile long cnt = 0; /* Counter */
sem_t mutex;
int sem_init(sem_t *s,0,unsigned int val);
void P(sem_t *s);
void V(sem_t *s);
int main(int argc, char **argv)
{
long niters;
int i, nthreads;
pthread_t tid[1000];
niters = atoi(argv[1]);
nthreads = atoi(argv[2]);
for (i=0; i < nthreads; i++)
{
sem_init(&mutex,0,1);
pthread_create(&tid[i], NULL, thread, &niters);
printf("THREAD %d with tid= %ld CREATED \n", i, tid[i]);
}
for (i=0; i < nthreads; i++)
{
pthread_join(tid[i], NULL);
printf("THREAD %d with tid= %ld TERMINATED \n", i, tid[i]);
}
/* Check result */
if (cnt != (nthreads * niters))
printf("BOOM! cnt=%ld --- RACE CONDITION\n", cnt);
else
printf("OK cnt=%ld\n", cnt);
printf("PRESS CTRL-C to terminate or CTRL-Z to suspend \n");
pause();
exit(0);
}
/* Thread routine */
void *thread(void *vargp)
{
long i, niters = *((long *)vargp);
for (i = 0; i < niters; i++)
{
P(&mutex);
cnt++;
V(&mutex);
}
return NULL;
}
I want to synchronize threads using semaphores, but when I declare the sem_init() function and make the middle argument 0, it gives me an error. Maybe the function is wrong. I also included the semaphore.h header.
Please suggest a solution.
in this example code below, where is the "critical section" exatly?. after "sem_wait()" ?
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
void * thread_snd(void *arg);
void * thread_rcv(void *arg);
sem_t bin_sem;
int number=0;
char thread1[]="A Thread";
char thread2[]="B Thread";
char thread3[]="C Thread";
int main(int argc, char **argv)
{
pthread_t t1, t2, t3;
void *thread_result;
int state;
state = sem_init(&bin_sem, 0, 0);
pthread_create(&t1, NULL, thread_snd, &thread1);
pthread_create(&t2, NULL, thread_rcv, &thread2);
pthread_create(&t3, NULL, thread_rcv, &thread3);
pthread_join(t1, &thread_result);
pthread_join(t2, &thread_result);
pthread_join(t3, &thread_result);
printf("number : %d \n", number);
sem_destroy(&bin_sem);
return 0;
}
void * thread_snd(void * arg)
{
int i;
for(i=0; i<4; i++)
{
while(number != 0)
sleep(1);
number++;
printf("%s, number : %d \n", (char*)arg, number);
sem_post(&bin_sem);
}
}
void * thread_rcv(void * arg)
{
int i;
for(i=0; i<2; i++)
{
sem_wait(&bin_sem);
number--;
printf("%s, number : %d \n", (char*)arg, number);
}
}
There actually is no "critical section" in the provided code, there is only "sync point", and yes that is realized with the semaphore. The critical section can also be implemented with semaphore, but then the thread must use both sem_wait() and sem_post() but in most cases mutexes are used for critical sections (if only one thread is ever supposed to enter it).
I am trying to create a thread and from what I remember this should be the right way to do it:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
int SharedVariable =0;
void SimpleThread(int which)
{
int num,val;
for(num=0; num<20; num++){
if(random() > RAND_MAX / 2)
usleep(10);
val = SharedVariable;
printf("*** thread %d sees value %d\n", which, val);
SharedVariable = val+1;
}
val=SharedVariable;
printf("Thread %d sees final value %d\n", which, val);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t< NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, SimpleThread, (void* )t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
And the error that I'm getting is this one:
test.c: In function ‘main’: test.c:28: warning: passing argument 3 of
‘pthread_create’ from incompatible pointer type
/usr/include/pthread.h:227: note: expected ‘void * (*)(void *)’ but
argument is of type ‘void (*)(int)’
I cannot change the SimpleThread function so changing the type of the parameter is not an option even though I already tried and it didn't work either.
What am I doing wrong?
SimpleThread should be declared as
void* SimpleThread(void *args) {
}
When you pass parameters to your thread, it is best to define a struct for them, pass a pointer to that struct as void*, and cast back to the right type inside the function.
Here's a compiling and "working" version of your program, although I have to admit to not knowing exactly what it's doing. For the critics in the audience, I apologize in advance for the pthread_join loop at the end.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 5
struct my_thread_info {
long which;
};
int SharedVariable = 0;
void *SimpleThread(void *data)
{
int num, val;
struct my_thread_info *info = data;
for (num = 0; num < 20; num++) {
if (random() > RAND_MAX / 2)
usleep(10);
val = SharedVariable;
printf("*** thread %ld sees value %d\n", info->which, val);
SharedVariable = val + 1;
}
val = SharedVariable;
printf("Thread %ld sees final value %d\n", info->which, val);
free(info);
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
struct my_thread_info *info;
for (t = 0; t < NUM_THREADS; t++) {
printf("In main: creating thread %ld\n", t);
info = malloc(sizeof(struct my_thread_info));
info->which = t;
rc = pthread_create(&threads[t], NULL, SimpleThread, info);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
for (t = 0; t < NUM_THREADS; t++) {
pthread_join(threads[t], NULL);
}
}