I am new to C and trying out conditional critical region. I read up on a couple of sites about Wait() and Signal() but I just can't figure out what my issue is. Hopefully somebody here can point me in the right direction what I am doing wrong here.
I am trying to do make two threads in my sample program here. Thread 1 will assign a value to String stuff and Thread 2 will print the info of the String.
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
void Lock(pthread_mutex_t m);
void Unlock(pthread_mutex_t m);
void Wait(pthread_cond_t t, pthread_mutex_t m);
void Signal(pthread_cond_t);
void Broadcast(pthread_cond_t t);
void* First(void* args);
void* Second(void* args);
char* stuff;
int main(int argc, char** argv){
pthread_t r1, r2;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
if(pthread_create(&r1, NULL, First, NULL))
fprintf(stderr,"Error\n");
if(pthread_create(&r2, NULL, Second, NULL))
fprintf(stderr, "Error\n");
pthread_join(r1, NULL);
pthread_join(r2, NULL);
}
void* First(void* args){
Lock(mutex);
stuff = "Processed";
usleep(500000);
Broadcast(cond);
Unlock(mutex);
pthread_exit(NULL);
return NULL;
}
void* Second(void* args){
Lock(mutex);
Wait(cond, mutex);
usleep(500000);
printf("%s", stuff);
Unlock(mutex);
pthread_exit(NULL);
return NULL;
}
void Lock(pthread_mutex_t m){
pthread_mutex_lock(&m);
}
void Unlock(pthread_mutex_t m){
pthread_mutex_unlock(&m);
}
void Wait(pthread_cond_t t, pthread_mutex_t m){
pthread_cond_wait(&t, &m);
}
void Signal(pthread_cond_t t){
pthread_cond_signal(&t);
}
void Broadcast(pthread_cond_t t){
pthread_cond_broadcast(&t);
}
I face a deadlock when executing this code but I am not sure why. GDB mentions that it stops at Wait() but I am not sure why.
Related
I got this simple C program that uses pthreads.
I basically want to call my_function() once I'm 100% sure that my_thread() gets called and is executed.
I need to know how to synchronize the main() function and the my_thread() function.
Please note that the my_thread() never returns.
#include <stdio.h>
#include <pthread.h>
void my_function (void);
void* my_thread (void* arg);
int main (int argc, char* argv[])
{
int rc;
pthread_t id;
rc = pthread_create(&id, NULL, my_thread, NULL);
if (rc != 0)
{
return -10;
}
/*
* I wanna call my_function() once I'm 100% sure my_thread() gets called and being executed
*/
/*
* Synchronization code to add here:
*/
my_function();
return 0;
}
void* my_thread (void* arg)
{
/*
* This pthread never returns
*/
while (1)
{
/* stuff */
};
}
void my_function (void)
{
printf("Hello\n");
}
Thanks for your help.
Can anybody check if this solution is correct?
It works using the debugger but I would like to have a comment from experienced programmers.
#include <stdio.h>
#include <pthread.h>
void my_function (void);
void* my_thread (void* arg);
int started;
pthread_mutex_t mutex;
pthread_t id;
int main (int argc, char* argv[])
{
int rc;
int done;
started = 0;
mutex = PTHREAD_MUTEX_INITIALIZER;
rc = pthread_create(&id, NULL, my_thread, NULL);
if (rc != 0)
{
return -10;
}
/*
* Synchronization code proposed:
*/
done = 0;
do
{
pthread_mutex_lock(&mutex);
if (started == 1)
{
done = 1;
}
pthread_mutex_unlock(&mutex);
}
while (done == 0);
/*
* I wanna call my_function() once I'm 100% sure
* that my_thread() is called and being executed
*/
my_function();
return 0;
}
void* my_thread (void* arg)
{
started = 1;
while (1)
{
/* stuff */
};
}
void my_function (void)
{
printf("Hello\n");
}
It gets me error at rand_r
undefined reference to 'rand_r'
It is my first program at c language
I must use rand_r to threads, but i don't know what to do.
Please help me. Thank you
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "p3160062.h"
int cook;
int oven;
int prep;
int bake;
pthread_mutex_t lock;
pthread_t thread_id[100];
unsigned int seed;
int a;
void *myThread(void *vargp)
{
pthread_mutex_lock(&lock);
a=rand_r(&seed)%6;
while(a==0){
a=rand_r(&seed)%6;
}
printf("a=%d\n",a);
sleep(1);
printf("In thread\n");
pthread_mutex_unlock(&lock);
return NULL;
}
int main(void)
{
seed=1;
int i=0;
printf("Before Thread\n");
for(i=0;i<100;i++){
pthread_create(&(thread_id[i]), NULL, myThread, NULL);
pthread_join(thread_id[i], NULL);
seed++;
}
printf("After Thread\n");
pthread_mutex_destroy(&lock);
exit(0);
}
I'm trying to have a thread, that waits until a task is assigned and then will do it, however I'm running into complications.
#include "dispatchQueue.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
task_t *task;
void test1() {
sleep(1);
printf("test1 running\n");
}
void* do_stuff(void *args) {
printf("in do stuff\n");
pthread_mutex_lock(&mutex);
printf("after do stuff has lock\n");
task_t *task = (task_t *)args;
(task->work) (task->params);
pthread_mutex_unlock(&mutex);
}
int main(int argc, char** argv) {
pthread_t thread;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_mutex_lock(&mutex);
printf("after main gets lock\n");
pthread_create(&thread, NULL, do_stuff, task);
task = task_create(test1, NULL, "test1");
pthread_mutex_unlock(&mutex);
printf("after main unlocks \n");
pthread_join(thread, NULL);
}
The above code will give a segfault, however if I switch the lines pthread_create and task = task_create(), then it works fine. I'm not familiar with C at all, so I'm wondering why this is?
This is how task is created if that helps, at this point I'm pretty sure it's a problem with the way I'm using pthreads.
task_t *task_create(void (*work)(void *), void *param, char* name) {
task_t *task_ptr = malloc(sizeof(task_t));
if (task_ptr == NULL) {
fprintf(stderr, "Out of memory creating a new task!\n");
return NULL;
}
task_ptr->work = work;
task_ptr->params = param;
strcpy(task_ptr->name, name);
return task_ptr;
}
pthread_create(&thread, NULL, do_stuff, task);
task = task_create(test1, NULL, "test1");
You're passing junk to the thread. You haven't set task to any particular value here, yet you pass it to the thread as a parameter.
void* do_stuff(void *args) { // *** args is garbage here
printf("in do stuff\n");
pthread_mutex_lock(&mutex);
printf("after do stuff has lock\n");
task_t *task = (task_t *)args; // ** So task is garbage here
(task->work) (task->params);
pthread_mutex_unlock(&mutex);
}
Here, you initialize task from args. But args has a garbage value.
If you have some kind of collection that's going to track what tasks a thread is going to work on, you have to pass the thread a parameter that allows it to reliably find that collection. In this particular case, &task would work.
I have 4 processed called A, B, C, D in 4 thread, They printf their name. I want use mutex to process A, B, C, D run in order A, B, C, D. This is my code but it don't work such as me think. How to they work?
#include <stdio.h>
#include <pthread.h>
void processA();
void processB();
void processC();
void processD();
pthread_mutex_t mutex;
void main(){
pthread_t thread1;
pthread_t thread2;
pthread_t thread3;
pthread_t thread4;
pthread_mutex_init(&mutex,NULL);
pthread_create(&thread1, NULL, (void *)&processA,NULL);
pthread_create(&thread2, NULL, (void *)&processB,NULL);
pthread_create(&thread3, NULL, (void *)&processC,NULL);
pthread_create(&thread4, NULL, (void *)&processD,NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
pthread_join(thread4, NULL);
pthread_mutex_destroy(&mutex);
}
void processA()
{
while (1)
{
pthread_mutex_lock(&mutex);
printf("A \n");
pthread_mutex_unlock(&mutex);
}
}
void processB()
{
while (1)
{
pthread_mutex_lock(&mutex);
printf("B \n");
pthread_mutex_unlock(&mutex);
}
}
void processC()
{
while (1)
{
pthread_mutex_lock(&mutex);
printf("C \n");
pthread_mutex_unlock(&mutex);
}
}
void processD()
{
pthread_mutex_lock(&mutex);
while (1)
{
pthread_mutex_lock(&mutex);
printf("D \n");
pthread_mutex_unlock(&mutex);
}
}
mutex is for creating mutual exclusion on some context. For example if you have an object that should be reached by one thread at a time, you can use mutex.
You should use 3 semaphores for implementing such feature. You can say:
//semaphore1 = up, semaphore2 = up, semaphore3 = up
//Thread A
//wait for semaphore1 is up
//work
//make semaphore1 down
//Thread B
//wait for semaphore1 is down
//work
//make semaphore2 down
//Thread C
//wait for semaphore2 is down
//work
//make semaphore3 down
//Thread D
//wait for semaphore3 is down
//work
Well this is how you can do it, you just use mutex for the mutual variable (f in this case) and a pthread conditional signal to trigger the action of one thread per second. All of the threads get the signal but only one can access the mutex.
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <memory.h>
#include <stdarg.h>
#include <pthread.h>
pthread_mutex_t v1 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t v2 = PTHREAD_COND_INITIALIZER;
int f = 0;
void *processA(){
while(1){
pthread_mutex_lock(&v1);
pthread_cond_wait(&v2,&v1);
printf("A,%d\n",f);
f++;
pthread_mutex_unlock(&v1);
}
return NULL;
}
void *processB(){
while(1){
pthread_mutex_lock(&v1);
pthread_cond_wait(&v2,&v1);
printf("B,%d\n",f);
f++;
pthread_mutex_unlock(&v1);
}
return NULL;
}
void *processC(){
while(1){
pthread_mutex_lock(&v1);
pthread_cond_wait(&v2,&v1);
printf("C,%d\n",f);
f++;
pthread_mutex_unlock(&v1);
}
void main(){
pthread_t *h;
int i,ptnum = 3;
h = malloc(sizeof(pthread_t)*ptnum);
pthread_create(&h[0],NULL,processA,NULL);
pthread_create(&h[1],NULL,processB,NULL);
pthread_create(&h[2],NULL,processC,NULL);
while(f<=30){
pthread_cond_signal(&v2);
sleep(1);
}
pthread_mutex_lock(&v1);
printf("Main Mutex\n");
for(i=0;i<ptnum;i++){
pthread_join(&h[i],PTHREAD_CANCELED);
}
pthread_mutex_unlock(&v1);
return NULL;
}
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;
}