Προς το περιεχόμενο

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • 0
AfterForever

Δημιουργία πολλών διεργασιών

Ερώτηση

Καλημέρα.

Θέλω να δημιουργήσω 4 διεργασίες σε ένα πρόγραμμα για παράδειγμα.

Προφανώς να κάνω το εξής :

for(i=0;i<4;i++) fork();

δε θα δουλέψει, γιατί κάθε διεργασία μετά θα δημιουργήσει τα δικά της παιδιά, οπότε θα έχω παραπάνω από 4.

Τι μπορώ να κάνω; Κ επίσης μετά πως μπορώ να τις ξεχωρίσω;

Ευχαριστώ

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Προτεινόμενες αναρτήσεις

Κοινό address space και διεργασίες δεν πάνε μαζί - για αυτή την περίπτωση έχεις τα threads. Οι διεργασίες υποτίθεται πως δεν μοιράζονται τίποτα.

 

Βέβαια από την άλλη υπάρχουν τα pipes, message passing, RPC κλπ κλπ

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Δε χρειάζεσαι σημαφόρους σ' αυτήν την περίπτωση, αφού δεν έχεις ταυτόχρονες εγγραφές στην ίδια περιοχή μνήμης.

 

Στο περίπου:

>
 int pids[n+1] = {shared memory, μηδενικά};

 pids[0] = getpid(); //πατέρας
 for (i=1; i<n+1; i++)
   if(pid=fork()==0) //παιδί
     pids[i] = getpid();

 

Και στη συνέχεια ελέγχεις απλά (read only - δε χρειάζεται semaphore) το pids, αν είναι <> 0 τότε η διεργασία i έχει ξεκινήσει, αλλιώς αν θες την περιμένεις...

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Dop, ο λόγος που βγήκε η κοινή μνήμη είναι ειδικά για τις διεργασίες... Τα threads δεν έχουν "διαμοιραζόμενη μνήμη" (shared memory), αλλά έχουν την ίδια μνήμη, το ίδιο data segment (αυτό δεν λέγεται "κοινή").

 

Διάβασε λίγο στο manual της shmget, μόνο για process groups και fork μιλάει, καμία αναφορά σε threads (όχι ότι δεν γίνεται να χρησιμοποιηθεί και από threads, απλά δεν έχει νόημα, αφού έχουν το ίδιο data segment συνήθως δεν χρειάζονται και shared memory).

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

>
    if( (pid[i]=fork())==0) )	/* Αριστερές παρενθέσεις: 3, δεξιές παρενθέσεις: 4 */

 

:-)

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Ε μπορεί να το έγραψα λάθος εδώ.

>
for(i=0;i<4;i++){
	if( (pid[i]=fork())==0 ) 
		break;
}
for(i=0;i<4;i++){
	if(getpid()==pid[i])
		printf("process no%d--->pid=%d\n",i,pid[i]);	
}
return 0;

 

Αυτό γίνεται κανονικά compile, απλά δεν κάνει τίποτα. Που σημαίνει ότι η συνθήκη στο if δεν ισχύει.

Βέβαια αν έχω απλά βάλω ένα getpid() χωρίς επανάληψη, μου βγάζει κανονικά 5 διεργασίες

process no0--->pid=8334 with parent 8333

process no1--->pid=8335 with parent 8333

process no2--->pid=8336 with parent 8333

process no3--->pid=8337 with parent 8333

process no4--->pid=8333 with parent 7358

 

Επαναλαμβάνω, πως γίνεται να πω;: ο μπαμπάς θα κάνει αυτό, το πρώτο παιδί αυτό, το δεύτερο αυτό κοκ ?

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
>
int ppid=getpid();
for(i=0;i<=n;i++){
	if( ( (pid = fork() ) ) == 0 ){
		pids[i]=getpid();
		break;
	//	ftiaxtikan ta paidia
	}
}

if(getpid()==ppid){ 		//pateras
               for(i=0;i<=n;i++)
         		waitpid();
      	// mpla mpla
	exit(-1);
}

if(getpid()==pids[0]){  //to prwto paidi
                //mpla mpla
	exit(-1);	
}
for(i=1;i<=n;i++){
	if(getpid()==pids[i]){ // ta alla paidia
               //mpla mpla
	exit(-1);
	}
}

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

RETURN VALUES

Upon successful completion' date=' fork() returns a value of 0 to the child

process and returns the process ID of the child process to the parent

process. Otherwise, a value of -1 is returned to the parent process, no

child process is created, and the global variable errno is set to indi-

cate the error.

[/quote']

 

Άρα

>
for ...
 if ((pid[ί]=fork()) == 0)
   break;

 

Και τις ξεχωρίζεις με το pid[ί] από τον parent. Στους clients ο πίνακας pid[ί] δεν θα είναι έγκυρος.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Ενδιαφέρον.. Δεν είχα υπόψην το συγκεκριμένο τρόπο επικοινωνίας - ιδιαίτερα τους semaphores για αυτή τη δουλειά.

 

Και έχεις δίκιο για το shared memory. Από κλασική μου απροσεξία ήθελα να γράψω address space.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Τα έχω κοιτάξει τα manuals. Δε μπόρεσα όμως ξεκάθαρα να βγάλω άκρη. Προφανώς εμένα μου κάνει η wait4().

Το κλειδί είναι προφανώς εδώ :

The pid parameter specifies the set of child processes for which to wait.

If pid is -1, the call waits for any child process. If pid is 0, the

call waits for any child process in the process group of the caller. If

pid is greater than zero, the call waits for the process with process id

pid. If pid is less than -1, the call waits for any process whose

process group id equals the absolute value of pid.

 

Τι σημαίνει "set of child processes" ?

Έχω ένα πίνακα pids[] στην κοινή μνήμη για να βλέπουν όλοι τα pids και να στέλνουν τα αντίστοιχα σήματα. Έβαλα κάτι της μορφής στον πατέρα :

> for(i=0;i<=n;i++) wait4(pids[i]); 

Αλλά ο κώδικας μετά από αυτή την εντολή του πατέρα εκτελείται και πάλι (έχω βάλει κάτι εκτυπώσεις για να ξέρω που βρίσκομαι).

Είναι λογικό;

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Φίλε AfterForever,

 

αν θέλεις περιγράφεις πως το έλυσες διότι αντιμετωπίζω ακριβώς το ίδιο πρόβλημα...

 

Ευχαριστώ

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Ευχαριστώ κατ' αρχάς για την απάντηση :)

Λοιπόν εγώ έχω κάποιο αριθμό διεργασιών, οι οποίες πρέπει να στέλνουν δεδομένα η μία στην άλλη, ουσιαστικά μέσω κοινής μνήμης και σημαφόρων (αυτά θα τα υλοποιήσω στη συνέχεια).

Πως όταν έχουμε μόνο γονέα και παιδί, που λέμε:

>
pid=fork();
if(pid==0) // παιδί
else          // γονέας

 

Με μεγαλύτερο αριθμό διεργασιών (δηλαδή ένα γονέα και 3 παιδιά για παράδειγμα), πως θα ξεχωρίσουμε τα παιδιά ώστε καθένα από αυτά να κάνει τη δική του δουλειά; Δηλαδή τι συνθήκες πρέπει να βάλουμε στα if ; (Δεδομένου κιόλας ότι ο πίνακας που φτιάξαμε πριν δε φαίνεται από τα παιδιά).

Ευχαριστώ

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Μετά αν θέλω να συνεχίσουν οι διεργασίες να δουλεύουν ξεχωριστά πράγματα η κάθε μία, μπορώ μετά τον κώδικα να κάνω αυτό :

if(getpid()==pid)

και να ξεχωρίσω έτσι τις διεργασίες; Θα δουλέψει;

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
×
×
  • Δημιουργία νέου...