Mutex lock threads

丶灬走出姿态 提交于 2019-12-29 03:21:06

问题


Am new to multi threaded/processs programming. So here's what I need to clarify.

Process A code

pthread_mutex_lock()
    pthread_create(fooAPI(sharedResource)) //fooAPI creates another thread with shared resource that shares across processes.
pthread_mutex_unlock()

With the above pseudo code, is process B able to access sharedResource if mutex is not unlocked?

How can I access the sharedResource from process B correctly?

Any there any clear visual diagram that explains the relationship between mutexes, threads and processes?


回答1:


What you need to do is to call pthread_mutex_lock to secure a mutex, like this:

pthread_mutex_lock(&mutex);

Once you do this, any other calls to pthread_mutex_lock(mutex) will not return until you call pthread_mutex_unlock in this thread. So if you try to call pthread_create, you will be able to create a new thread, and that thread will be able to (incorrectly) use the shared resource. You should call pthread_mutex_lock from within your fooAPI function, and that will cause the function to wait until the shared resource is available.

So you would have something like this:

#include <pthread.h>
#include <stdio.h>

int sharedResource = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* fooAPI(void* param)
{
    pthread_mutex_lock(&mutex);
    printf("Changing the shared resource now.\n");
    sharedResource = 42;
    pthread_mutex_unlock(&mutex);
    return 0;
}

int main()
{
    pthread_t thread;

    // Really not locking for any reason other than to make the point.
    pthread_mutex_lock(&mutex);
    pthread_create(&thread, NULL, fooAPI, NULL);
    sleep(1);
    pthread_mutex_unlock(&mutex);

    // Now we need to lock to use the shared resource.
    pthread_mutex_lock(&mutex);
    printf("%d\n", sharedResource);
    pthread_mutex_unlock(&mutex);
}

Edit: Using resources across processes follows this same basic approach, but you need to map the memory into your other process. Here's an example using shmem:

#include <stdio.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/mman.h>
#include <sys/wait.h>

struct shared {
    pthread_mutex_t mutex;
    int sharedResource;
};

int main()
{
    int fd = shm_open("/foo", O_CREAT | O_TRUNC | O_RDWR, 0600);
    ftruncate(fd, sizeof(struct shared));

    struct shared *p = (struct shared*)mmap(0, sizeof(struct shared),
        PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

    p->sharedResource = 0;

    // Make sure it can be shared across processes
    pthread_mutexattr_t shared;
    pthread_mutexattr_init(&shared);
    pthread_mutexattr_setpshared(&shared, PTHREAD_PROCESS_SHARED);

    pthread_mutex_init(&(p->mutex), &shared);

    int i;
    for (i = 0; i < 100; i++) {
        pthread_mutex_lock(&(p->mutex));
        printf("%d\n", p->sharedResource);
        pthread_mutex_unlock(&(p->mutex));
        sleep(1);
    }

    munmap(p, sizeof(struct shared*));
    shm_unlink("/foo");
}

Writing the program to make changes to p->sharedResource is left as an exercise for the reader. :-)

Forgot to note, by the way, that the mutex has to have the PTHREAD_PROCESS_SHARED attribute set, so that pthreads will work across processes.




回答2:


Q1.) Assuming process B tries to take ownership of the same mutex you locked in process A (you left that out of your pseudocode) then no, process B cannot access sharedResource while the mutex is locked since it will sit waiting to lock the mutex until it is released by process A. It will return from the mutex_lock() function when the mutex is locked (or when an error occurs!)

Q2.) In Process B, ensure you always lock the mutex, access the shared resource, and then unlock the mutex. Also, check the return code from the mutex_lock( pMutex ) routine to ensure that you actually own the mutex, and ONLY unlock the mutex if you have locked it. Do the same from process A.

Both processes should basically do the same thing when accessing the mutex.
lock() If the lock succeeds, then { access sharedResource unlock() }

Q3.) Yes, there are lots of diagrams: =) https://www.google.se/search?q=mutex+thread+process&rlz=1C1AFAB_enSE487SE487&um=1&ie=UTF-8&hl=en&tbm=isch&source=og&sa=N&tab=wi&ei=ErodUcSmKqf54QS6nYDoAw&biw=1200&bih=1730&sei=FbodUbPbB6mF4ATarIBQ




回答3:


A process consists of at least one thread (think of the main function). Multi threaded code will just spawn more threads. Mutexes are used to create locks around shared resources to avoid data corruption / unexpected / unwanted behaviour. Basically it provides for sequential execution in an asynchronous setup - the requirement for which stems from non-const non-atomic operations on shared data structures.

A vivid description of what mutexes would be the case of people (threads) queueing up to visit the restroom (shared resource). While one person (thread) is using the bathroom easing him/herself (non-const non-atomic operation), he/she should ensure the door is locked (mutex), otherwise it could lead to being caught in full monty (unwanted behaviour)




回答4:


Below, code snippet, will help you in understanding the mutex-lock-unlock concept. Attempt dry-run on the code. (further by varying the wait-time and process-time, you can build you understanding).

Code for your reference:

#include <stdio.h>
#include <pthread.h>

void in_progress_feedback(int);

int global = 0;
pthread_mutex_t mutex;
void *compute(void *arg) {

    pthread_t ptid = pthread_self();
    printf("ptid : %08x \n", (int)ptid);    

    int i;
    int lock_ret = 1;   
    do{

        lock_ret = pthread_mutex_trylock(&mutex);
        if(lock_ret){
            printf("lock failed(%08x :: %d)..attempt again after 2secs..\n", (int)ptid,  lock_ret);
            sleep(2);  //wait time here..
        }else{  //ret =0 is successful lock
            printf("lock success(%08x :: %d)..\n", (int)ptid, lock_ret);
            break;
        }

    } while(lock_ret);

        for (i = 0; i < 10*10 ; i++) 
        global++;

    //do some stuff here
    in_progress_feedback(10);  //processing-time here..

    lock_ret = pthread_mutex_unlock(&mutex);
    printf("unlocked(%08x :: %d)..!\n", (int)ptid, lock_ret);

     return NULL;
}

void in_progress_feedback(int prog_delay){

    int i=0;
    for(;i<prog_delay;i++){
    printf(". ");
    sleep(1);
    fflush(stdout);
    }

    printf("\n");
    fflush(stdout);
}

int main(void)
{
    pthread_t tid0,tid1;
    pthread_mutex_init(&mutex, NULL);
    pthread_create(&tid0, NULL, compute, NULL);
    pthread_create(&tid1, NULL, compute, NULL);
    pthread_join(tid0, NULL);
    pthread_join(tid1, NULL);
    printf("global = %d\n", global);
    pthread_mutex_destroy(&mutex);
          return 0;
}


来源:https://stackoverflow.com/questions/14888027/mutex-lock-threads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!