38

マルチスレッド/プロセスプログラミングは初めてです。これが私が明確にする必要があることです。

コードを処理する

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

上記の擬似コードで、sharedResourceミューテックスのロックが解除されていない場合、プロセスBはアクセスできますか?

プロセスBからsharedResourceに正しくアクセスするにはどうすればよいですか?

ミューテックス、スレッド、プロセス間の関係を説明する明確な視覚的な図はありますか?

4

4 に答える 4

65

次のように、pthread_mutex_lock を呼び出してミューテックスを保護する必要があります。

pthread_mutex_lock(&mutex);

これを行うと、このスレッドで呼び出すまで、他の呼び出しpthread_mutex_lock(mutex)は返されません。pthread_mutex_unlockそのため、pthread_create を呼び出そうとすると、新しいスレッドを作成でき、そのスレッドは共有リソースを (誤って) 使用できるようになります。pthread_mutex_lock関数内から呼び出す必要fooAPIがあります。これにより、関数は共有リソースが利用可能になるまで待機します。

したがって、次のようなものになります。

#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);
}

編集:プロセス間でリソースを使用する場合は、これと同じ基本的なアプローチに従いますが、メモリを他のプロセスにマップする必要があります。以下は、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");
}

p->sharedResource を変更するプログラムの作成は、読者の課題として残されています。:-)

ところで、pthreads がプロセス間で動作するようにするには、ミューテックスに PTHREAD_PROCESS_SHARED 属性を設定する必要があることに注意するのを忘れていました。

于 2013-02-15T04:15:11.637 に答える
4

Q1.) プロセス B が、プロセス A でロックした同じミューテックスの所有権を取得しようとすると (疑似コードから除外した場合)、いいえ、プロセス B はミューテックスがロックされている間は sharedResource にアクセスできません。プロセス A によって解放されるまで、mutex がロックされると (またはエラーが発生すると!)、mutex_lock() 関数から戻ります。

Q2.) プロセス B では、必ずミューテックスをロックし、共有リソースにアクセスしてから、ミューテックスをロック解除してください。また、mutex_lock( pMutex ) ルーチンからの戻りコードをチェックして、ミューテックスを実際に所有していることを確認し、ロックしている場合にのみミューテックスのロックを解除してください。プロセスAから同じことを行います。

ミューテックスにアクセスするとき、両方のプロセスは基本的に同じことを行う必要があります。
lock() ロックが成功した場合、{ access sharedResource unlock() }

Q3.) はい、たくさんの図があります: =) 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

于 2013-02-15T04:37:39.083 に答える
3

以下のコード スニペットは、mutex-lock-unlock の概念を理解するのに役立ちます。コードの予行演習を試みます。(さらに、待ち時間と処理時間を変えることで、理解を深めることができます)。

参照用のコード:

#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;
}
于 2015-09-07T11:56:34.020 に答える
3

プロセスは少なくとも 1 つのスレッドで構成されます (メイン関数を考えてください)。マルチスレッド コードは、より多くのスレッドを生成するだけです。ミューテックスは、共有リソースの周りにロックを作成して、データの破損/予期しない/望ましくない動作を回避するために使用されます。基本的に、非同期セットアップでの順次実行を提供します-その要件は、共有データ構造に対する非 const 非アトミック操作に由来します。

トイレ (共有リソース) を訪れるために列に並ぶ人々 (スレッド) の場合のミューテックスの明確な説明。1 人 (スレッド) がバスルームを使用している間 (non-const 非アトミック操作)、彼/彼女はドアがロックされていることを確認する必要があります (ミューテックス)。 )

于 2013-02-15T04:41:11.817 に答える