2015-11-10 16 views
5
#include <stdio.h> 
#include <sys/types.h> 
#include <iostream> 
#include <unistd.h> 
#include <fstream> 
#include <string> 
#include <semaphore.h> 

using namespace std; 

int main(int argc, char *argv[]){ 
    int pshared = 1; 
    unsigned int value = 0; 
    sem_t sem_name; 
    sem_init(&sem_name, pshared, value); 

    int parentpid = getpid(); 
    pid_t pid = fork(); 

    if (parentpid == getpid()){ 
    cout << "parent id= " << getpid() << endl; 
    sem_wait(&sem_name); 
    cout << "child is done." << endl; 
    } 

    if (parentpid != getpid()){ 
    cout << "child id= " << getpid() << endl; 
    for (int i = 0; i < 10; i++) 
     cout << i << endl; 

    sem_post(&sem_name); 
} 
    sleep(4); 
    return 0; 
} 

परिणाम होना चाहिए:सैमफोर क्यों काम नहीं कर रहा है?

parent id 123456. 
child id 123457. 
0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
child is done. 

कार्यक्रम बाहर निकलता है, लेकिन इसके बजाय यह सेमाफोर का संकेत नहीं है।

+0

में आपका स्वागत है लिया! हमारे पास आपका कोड है और परिणाम क्या होना चाहिए ... वास्तविक परिणाम क्या है? आप कैसे सुनिश्चित हैं कि सेमफोर कभी संकेत नहीं दिया जाता है? क्या आप इसे जोड़ने के लिए अपना प्रश्न संपादित कर सकते हैं। अब तक मैं कुछ भी अपने कोड –

उत्तर

7

के साथ एक for पाश में प्रारंभिक घोषणा और प्रिंट था:

तो pshared है अशून्य, तो सेमाफोर प्रक्रियाओं के बीच साझा किया जाता है, और साझा स्मृति का एक क्षेत्र में स्थित होना चाहिए (देखें shm_open (3), mmap (2), और shmget (2))। किसी भी प्रक्रिया है कि साझा स्मृति क्षेत्र का उपयोग कर सकते sem_post का उपयोग कर सेमाफोर पर काम कर सकते हैं (के बाद से एक बच्चे कांटा द्वारा बनाई गई (2) अपने माता पिता की स्मृति मैपिंग विरासत में, यह भी सेमाफोर उपयोग कर सकते हैं।) (3), sem_wait (3) , आदि

पॉज़िक्स सेमफोर ऑन-द-स्टैक structs हैं। वे संदर्भित-संदर्भित संदर्भ नहीं हैं जैसे कि कर्नेल-रखरखाव संरचना जैसे दायरस्क्रिप्टर्स हैं। यदि आप दो प्रक्रियाओं के साथ एक पॉज़िक्स सेमफोर साझा करना चाहते हैं, तो आपको साझाकरण भाग का ख्याल रखना होगा।

यह काम करना चाहिए:

#include <fstream> 
#include <iostream> 
#include <semaphore.h> 
#include <stdio.h> 
#include <string> 
#include <sysexits.h> 
#include <sys/mman.h> 
#include <sys/types.h> 
#include <unistd.h> 


int main(int argc, char *argv[]){ 
    using namespace std; 
    sem_t* semp = (sem_t*)mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED, 0, 0); 
    if ((void*)semp == MAP_FAILED) { perror("mmap"); exit(EX_OSERR); } 

    sem_init(semp, 1 /*shared*/, 0 /*value*/); 

    pid_t pid = fork(); 
    if(pid < 0) { perror("fork"); exit(EX_OSERR); } 

    if (pid==0){ //parent 
    cout << "parent id= " << getpid() << endl; 
    sem_wait(semp); 
    cout << "child is done." << endl; 
    }else { //child 
    cout << "child id= " << getpid() << endl; 
    for (int i = 0; i < 10; i++) 
     cout << i << endl; 
    sem_post(semp); 
    } 
    return 0; 
} 

नोट: तुम सिर्फ इस व्यवहार चाहते हैं, तो जाहिर है waitpid जाने का रास्ता है। मुझे लगता है कि आप क्या चाहते हैं POSIX semaphores का परीक्षण करना है।

+0

में गलत एक काँटेदार बच्चे सेमाफोर तक पहुँचने के लिए माता-पिता के साथ एक साझा स्मृति क्षेत्र की आवश्यकता है खोजने के लिए प्रतीत नहीं कर सकता हूँ? क्या यह पर्याप्त है साझा कोड में सेमफोर को वैश्विक चर के रूप में घोषित करें? जब मैंने इसे पढ़ा तो मुझे भ्रमित करने वाले ब्रैकेट्स के बीच वाक्य मिला। –

+0

@dave_alcarin हाँ + कोई। मैंने कुछ उदाहरण कोड जोड़ा है। – PSkocik

+0

तो, एक साझा स्मृति की वास्तव में आवश्यकता है, लेकिन मैं यह मानता हूं कि मैन पेज ने क्या कहा है कि मानचित्रण (एमएमएपी से) विरासत में मिला है। अच्छा उदाहरण! +1 –

4

XY Problem?

कि आप क्या करना चाहते हैं प्रतीक्षा करने के लिए अपने बच्चे को इस प्रक्रिया से किया जा करने के लिए, आप सेमाफोर की आवश्यकता नहीं है, लेकिन wait या waitpid। निम्नलिखित सी कोड में आपके अपेक्षित आउटपुट हैं।

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

int main(void){ 
    pid_t pid; 
    pid = fork(); 
    if (pid < 0) { 
     fprintf(stderr, "fork failed!\n"); 
     return 1; 
    } 
    if (pid == 0) { 
     int i; 
     printf("child id= %d\n", getpid()); 
     for (i = 0; i < 10; i++) { 
      printf("%d\n",i); 
     } 
    } 
    else { 
     int status; 
     printf("parent id= %d\n", getpid()); 
     waitpid(-1, &status, 0); 
     printf("child is done\n"); 
    } 
    return 0; 
} 

नोट: मैं सी में किया था क्योंकि केवल सी ++ आप उपयोग कर रहे थे sem_init के मैनपेज से cout << "blah" << endl;

1
इसके बजाय sem_init() का उपयोग करने का

, sem_open() का उपयोग करें। इसका कारण यह है सेमाफोर साझा पता स्थान में करने के बजाय प्रक्रिया ढेर जहां यह fork() के माध्यम से दोहराया जाता है पर होने की जरूरत है।

#include <fcntl.h> 
... 

sem_t *sem_ptr; 
sem_ptr = sem_open("my_semaphore", O_CREAT, 0644, value); 
... 

sem_wait(sem_ptr); 
... 

sem_post(sem_ptr); 
... 

यू एंड एल से http://blog.superpat.com/2010/07/14/semaphores-on-linux-sem_init-vs-sem_open/

संबंधित मुद्दे