I have a C program where I wish to share a buffer between 2 threads. I also would like it to be thread safe so I want to pass a mutex as well. But since I can only pass 1 pointer to the thread I am trying to copy the mutex into the buffer, sending it and having the thread pull out the mutex and then use the buffer.
When the thread gets the mutex out, it has lost connection to the main thread's mutex. This is a silly example, but I would like the thread to lock the mutex and have the main thread get blocked, just to prove that this works. Currently the main thread goes on forever.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<stdbool.h>
#define BUFF 1024
void *func(void *buffer) {
pthread_mutex_t lock;
memcpy(&lock, buffer, sizeof(pthread_mutex_t));
pthread_mutex_lock(&lock); //example
// do stuff with buffer
}
int main() {
pthread_mutex_t lock;
if (pthread_mutex_init(&lock, NULL) != 0) {
printf("error in mutex init\n");
return 1;
}
void *sharedBuffer = calloc(1, BUFF);
memcpy(sharedBuffer, &lock, sizeof(pthread_mutex_t));
pthread_t handle;
pthread_create(&handle, NULL, func, sharedBuffer);
while (true) {
if (pthread_mutex_trylock(&lock) == 0) {
printf("in main\n");
if (*(int*)sharedBuffer != 0) {
//do stuff with shared buffer
}
pthread_mutex_unlock(&lock);
}
}
}
Is there a proper way to share a buffer and mutex between threads is C? All the ways I have tried one of the 2 loses its connection to main. Any thoughts are appreciated (except if you say to use globals)
Use a struct that holds the mutex and buffer.
You don't need to have a struct which holds the mutex; you need a struct which holds a pointer to a mutex.
Here is an example:
struct Arg {
pthread_mutex_t *lock;
char buf[BUFF];
};
You would initialize this struct like so (error checking omitted for brevity):
int main()
{
pthread_mutex_t lock;
pthread_mutex_init(&lock, NULL);
struct Arg *arg = calloc(1, sizeof(*arg));
arg->lock = &lock;
pthread_t handle;
pthread_create(&handle, NULL, func, arg);
...
In the thread function, do this:
void *func(void *buffer)
{
struct Arg *arg = (struct Arg *)buffer;
pthread_mutex_lock(arg->lock); // locks the same mutex as main.
...