POSIX C Threads. Mutex example. Don't work as expected
Asked Answered
S

2

8

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!

Servo answered 15/4, 2012 at 11:2 Comment(0)
H
16
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.

Howenstein answered 15/4, 2012 at 11:4 Comment(5)
I think it works :) This is my final code for anyone interested... pastebin.me/bc23773578d79a55882d7ced4e04b026Servo
Still broken. You only make sure one thread has finished when you destroy the mutex. What if the other one isn't done yet? There is no guarantee the thread will start, acquire the mutex, or finish in any particular order unless you force it somehow. (Lesson one of multithreading is this: Things are only assured to occur in a particular order if you force them to occur in that order.)Insensitive
Yes but I have both functions started in one thread, the only thread: mythread. Is it ok to do so or it's always safer to use one thread for one function?Servo
Anyway, I love you guys, you were so fast, it was some time since I was struggling with that problem. I always ignored the main thread.Servo
@JohnSmith Just make sure you joing both threads or you might destroy the mutex while another thread still holds it locked.Howenstein
B
2

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;
}
Bolide answered 11/12, 2014 at 7:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.