2013-10-04 158 views
7

我想創建n個並行運行的進程,讓它們鎖定一個互斥鎖,增加一個計數器,然後解鎖並退出。procs,fork()和互斥鎖

這裏是我的代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/wait.h> 
#include <sys/types.h> 
#include <sys/mman.h> 
#include <unistd.h> 
#include <pthread.h> 

pthread_mutex_t mutex; 

int main(int argc, char **argv) { 

    if (argc != 2) 
    return 0; 
    int n = atoi(argv[1]); 
    int i = 0; 
    int status = 0; 

    pthread_mutex_init(&mutex, NULL); 

    pid_t pid = 1; 
    static int *x; 
    x = mmap(NULL, sizeof *x, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); 
    *x = 0; 

    printf("Creating %d children\n", n); 

    for(i = 0; i < n; i++) { 
    if (pid != 0) 
     pid = fork(); 
    } 

    if (pid == 0) { 
    pthread_mutex_lock(&mutex); 
    *x = *x + 1; 
    printf("[CHLD] PID: %d PPID: %d X: %d\n", getpid(), getppid(), *x); 
    pthread_mutex_unlock(&mutex); 
    exit(0); 
    } 

    wait(&status); 

    printf("[PRNT] PID: %d X: %d\n", getpid(), *x); 
    munmap(x, sizeof *x); 

    return 0; 
} 

./procs 10000然而不返回X = 10000 我想這是因爲互斥沒有進程間共享,但什麼是正確的方法共享互斥量?

+0

我想你會發現使用'fork()'與interprorecess更容易使用信號量。見http://man7.org/linux/man-pages/man7/sem_overview.7.html和請參閱http://stackoverflow.com/questions/6477525/interprocess-mutex-with-pthreads – goji

+0

我有點想用互斥體,因爲我想實現使用相同互斥體的線程版本 – user1743798

+0

也可以在線程中使用信號量,但當然互斥體確實更合適。如果你感興趣,我做了一個使用信號量的例子。在這裏檢查:http://codepad.org/m1I9753u鏈接與-pthread – goji

回答

8

下面是使用pthread_mutex的評論中的示例端口。我第一次做到這一點,但似乎工作:

#include <stdio.h> 
#include <assert.h> 
#include <unistd.h> 
#include <stdbool.h> 
#include <fcntl.h> 
#include <sys/mman.h> 
#include <pthread.h> 

typedef struct 
{ 
    bool done; 
    pthread_mutex_t mutex; 
} shared_data; 

static shared_data* data = NULL; 

void initialise_shared() 
{ 
    // place our shared data in shared memory 
    int prot = PROT_READ | PROT_WRITE; 
    int flags = MAP_SHARED | MAP_ANONYMOUS; 
    data = mmap(NULL, sizeof(shared_data), prot, flags, -1, 0); 
    assert(data); 

    data->done = false; 

    // initialise mutex so it works properly in shared memory 
    pthread_mutexattr_t attr; 
    pthread_mutexattr_init(&attr); 
    pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 
    pthread_mutex_init(&data->mutex, &attr); 
} 

void run_child() 
{ 
    while (true) 
    { 
     puts("child waiting. .. "); 
     usleep(500000); 

     pthread_mutex_lock(&data->mutex); 
     if (data->done) { 
      pthread_mutex_unlock(&data->mutex); 
      puts("got done!"); 
      break; 
     } 
     pthread_mutex_unlock(&data->mutex); 
    } 

    puts("child exiting .."); 
} 

void run_parent(pid_t pid) 
{ 
    puts("parent sleeping .."); 
    sleep(2); 

    puts("setting done .."); 
    pthread_mutex_lock(&data->mutex); 
    data->done = true; 
    pthread_mutex_unlock(&data->mutex); 

    waitpid(pid, NULL, NULL); 

    puts("parent exiting .."); 
} 

int main(int argc, char** argv) 
{ 
    initialise_shared(); 

    pid_t pid = fork(); 
    if (!pid) { 
     run_child(); 
    } 
    else { 
     run_parent(pid); 
    } 

    munmap(data, sizeof(data)); 
    return 0; 
} 
+0

我認爲你有一些想法,你怎麼會出錯? :)你也可以接受也接受! ;> – goji

+0

是的,謝謝。看起來很像將結構傳遞給線程。很方便。 – user1743798

+0

很好的例子。我用它來回答一個單獨的帖子並引用這個答案。謝謝! – DevNull