Question

I'm completely new to pthreads and there seems to be a lot of unnecessary info on all the site I've looked at.

I have two functions let's just call them X and Y for now, these both work on blocks in memory. If one thread is running X I don't want any other threads to be calling X or Y on the same block, how can I make sure this will never happen?

Do I need to mutex lock the functions for certain block values?

Was it helpful?

Solution

Perhaps some demonstration code is in order. Presuming you have a block header like so:

struct block {
    void *data;
    size_t len;
};

You would protect the block by adding a mutex variable to this structure:

struct block {
    void *data;
    size_t len;
    pthread_mutex_t lock;
};

You then need to update the initialisation function for this structure to initialise the lock:

struct block *new_block(size_t len)
{
    struct block *b = malloc(sizeof *b);
    b->data = malloc(len);
    b->len = len;

    pthread_mutex_init(&b->lock, NULL);

    return b;
}

The X and Y functions (and any other function that reads or writes to the block) then need to take the lock and release it at exit:

int x(struct block *b)
{
    int retval;

    pthread_mutex_lock(&b->lock);

    /* code */

    pthread_mutex_unlock(&b->lock);
    return retval;
}

int y(struct block *b)
{
    int retval;

    pthread_mutex_lock(&b->lock);

    /* code */

    pthread_mutex_unlock(&b->lock);
    return retval;
}

You need to be careful to ensure that you unlock the mutex even in error return paths, too.

OTHER TIPS

You will need to use mutexes.

You should not lock code, you should lock data. Create a mutex for each block, and lock it while a function is operating on the block, then unlock it when finished.

A mutex is a type defined by pthread.h, pthread_mutex_t. Functions are provided to lock and unlock the mutex. These functions ensure that only one thread can gain a lock at a time (if you just used a variable to indicate that your block is being used, you will have concurrency issues with that variable instead of the block).

There are numerous tutorials available online. Google "pthread tutorial" and you should find enough to get yourself started.

You lock the resource - in this case a memory block - with a mutex. Alternatively you can lock just the parts of your functions code that read/update that area of memory. That is called a critical section, and requires a different approcch to coding. It means your threads are free to operate except when they hit that part where they interact with the resource.

The first method is easier to implement - just an all or nothing approach for the whole function X or Y.

Multi-threaded programming is really better resolved using in higher level languages. Some things are difficult to understand in C, and, in my opinion, mutli-threading is one of them. I've found Java gave me a better feel for the issues and problems. It has easier to understand concepts and easier to read documentation. A C++ framework such as Poco or Qt would also be better if Java is not your thing.

As others have said, conceptually you want to lock resources (in your case a section of memory). Semaphores, as a concept, fit this problem much better than mutex does. I would research semaphores and just think of mutexes as a building block of semaphores. If you ask me, a mutex is a poorly named binary semaphore.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top