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

Function pointer serialization σε C


gon1332

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

Δουλεύω με unix sockets και το message που θέλω να στείλω έχει κι ένα function pointer.

 

Γενικότερα δε βρήκα κάτι με googling. Είτε λένε πως είναι αδύνατο, ή μόνο με hacker-ιές. Βρήκα λύσεις μόνο για C++.

 

Τι έχετε να πείτε πάνω στο θέμα για C;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ο function pointer είναι μια μεταβλητη δείκτη, που εχει ως τιμή την θεση μνημης μιας συναρτησης στο πρόγραμμα. Εσύ τι θέλεις να στείλεις; Την τιμή της θέσης μνήμης ή τον κώδικα της συνάρτησης;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αν θες να στείλεις τον κώδικα της συνάρτησης, απλά γράψτον σε έναν πίνακα σαν αλφαριθμητικό και στείλτο έτσι. Αλλά αυτό που στέλνεις είναι απλά μια ακολουθία bytes.

 

Αν εννοείς πως θες να τρέξεις κιόλας αυτήν την συνάρτηση από την διεργασία που λαμβάνει το μήνυμα, αλλάζουν πολύ τα πράματα.

 

Δεν γίνεται να κατασκευάσεις κώδικα στο runtime μέσα στο ίδιο process (τα bytes που στέλνεις και λαμβάνεις δεν βρίσκονται σε εκτελέσιμη περιοχή μνήμης) παρά  μόνο αν κατασκευάσεις μέσα από το πρόγραμμά σου ένα άλλο εκτελέσιμο αρχείο, γράψεις σε αυτό την κατάλληλη γλώσσα μηχανής για αρχικοποίηση και προσθέσεις και τον κώδικα της συνάρτησης (σε γλώσσα μηχανής εννοείται), και τέλος να τρέξεις το καινούργιο εκτελέσιμο σαν παιδί της διεργασίας σου με καμια exec()

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δουλεύω με unix sockets και το message που θέλω να στείλω έχει κι ένα function pointer.

 

Γενικότερα δε βρήκα κάτι με googling. Είτε λένε πως είναι αδύνατο, ή μόνο με hacker-ιές. Βρήκα λύσεις μόνο για C++.

 

Τι έχετε να πείτε πάνω στο θέμα για C;

 

Τα message objects σου έχουν function pointer σαν member το οποίο θες και να το μεταφέρεις.

 

Κάτι μου κάνει πολύ λάθος σε αυτό το design συνολικά.

 

 

Γιατί να θες να μεταφέρεις ένα function pointer;

 

Σαν συμπεριφορά τι είναι αυτό που θέλεις να πετύχεις; (γιατί ο τρόπος που πας να το πετύχεις είναι ξεκάθαρα λάθος)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Το μοντέλο μου έχει ως εξής:

 

Έχω ένα main thread - coordinator- στο main process και πολλά worker processes. Ο coordinator διατηρεί μία ουρά από tasks, τα οποία tasks είναι δομές που έχουν κι ένα pointer στη συνάρτηση του task.

 

Το πρωτόκολλο ανάθεσης έχει ως εξής. Ο κάθε worker όσο δεν έχει work, στέλνει αιτήματα στον coordinator ώστε να του στείλει.

 

Θα με ρωτήσεις γιατί όχι threads; Δε θέλω shared memory model μεταξύ των workers και προφανώς και του coordinator (γιατί κάποια cores λειτουργούν σε ασταθή κατάσταση και υπάρχει περίπτωση ο ένας να χαλάσει η μνήμη αυτών που δουλεύουν κομπλέ). Οπότε χρησιμοποιήσα processes μιας και είναι εγγενής αυτή η ασφάλεια.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μία λύση θα μπορούσε να είναι η εξής.

 

Να κάνω compile τις συναρτήσεις ως shared library και να τις φορτώνω με dlopen(3) & dlsym(3).

Οπότε στο task πλέον δε θα έχω pointer function, αλλά το symbol της συνάρτησης ως char *.


Μετά βρήκα κι αυτό.

 

UPDATE:

Άκυρο παιδιά. Δεν υπάρχει κανένα θέμα με ό,τι έκανα.

 

Εφόσον έκανα fork, τότε και οι νέες διεργασίες έχω copy του text segment, οπότε και οι function pointers είναι έγκυροι αν τους μεταφέρω σε άλλη διεργασία. Όλα κομπλέ.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Εφοσον την δουλεια την κανουν οι workers, για πιο λογο εχεις τα "task" στο main; Καντα ξεχωριστα προγραμματα ωστε το μοντςλο σου να τρχει σε διαφορετικα nodes. Ετσι και αλλιως εισαι πανω σε σοκετ.

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Το μοντέλο μου έχει ως εξής:

 

Έχω ένα main thread - coordinator- στο main process και πολλά worker processes. Ο coordinator διατηρεί μία ουρά από tasks, τα οποία tasks είναι δομές που έχουν κι ένα pointer στη συνάρτηση του task.

 

Το πρωτόκολλο ανάθεσης έχει ως εξής. Ο κάθε worker όσο δεν έχει work, στέλνει αιτήματα στον coordinator ώστε να του στείλει.

 

Θα με ρωτήσεις γιατί όχι threads; Δε θέλω shared memory model μεταξύ των workers και προφανώς και του coordinator (γιατί κάποια cores λειτουργούν σε ασταθή κατάσταση και υπάρχει περίπτωση ο ένας να χαλάσει η μνήμη αυτών που δουλεύουν κομπλέ). Οπότε χρησιμοποιήσα processes μιας και είναι εγγενής αυτή η ασφάλεια.

 

Ωραία φάση, όμως...

 

Εφόσον θες να φτιάξεις κάτι έξω απο τη λογική του message queue ενός multithread application (και άρα κοινής μνήμης) και θες να βασίζεσαι αποκλειστικά σε socket - και για να είναι και εντελώς αυτόνομα τα processes (μεταφέροντας διεύθυνση μνήμης συνάρτησης προφανώς δε μιλάμε για αυτονομία) εγώ θα σου πρότεινα το εξής:

 

 

Τα messages θα έχουν μόνο data. Τίποτα άλλο.

Ο κάθε worker θα πρέπει να ξέρει ποια συνάρτηση "επεξεργασίας" να καλέσει για το κάθε task απο τα data και μόνο.

(πχ ένα defined κατα το compile time, map με συμβολική τιμή (enumerator φάση) και τη συνάρτηση που επεξεργάζεται αυτό τον τύπο task. Και κάθε task να έχει ένα taskType μεταβλητή ας πούμε απο αυτό το enumerator.)

 

Φαντάζομαι οτι όλες οι συναρτήσεις υπάρχουν απο το compile time σωστά; Και είναι γνωστές σε όλους (coordinator και workers) απο το compile time σωστά;

UPDATE:

Άκυρο παιδιά. Δεν υπάρχει κανένα θέμα με ό,τι έκανα.

 

Εφόσον έκανα fork, τότε και οι νέες διεργασίες έχω copy του text segment, οπότε και οι function pointers είναι έγκυροι αν τους μεταφέρω σε άλλη διεργασία. Όλα κομπλέ.

 

Το πρόβλημα για μένα είναι στη λογική. 

 

Αν κάνεις κάτι αυτόνομο (έστω και θεωρητικά) σε επίπεδο μνήμης, δεν μεταφέρεις function pointers. 

 

 

Αλλιώς πας σε λογική όπως είπα task queue σε multi thread περιβάλλον όπου εκεί δε χρειάζεσαι socket.

 

 

PS

Πάντως ωραία φάση αν και με χαλάει η C του πράγματος :)

(Με C++11 ή 14 θα πέταγα τη σκούφια μου).

 

Ωστόσο παίζει κανα github σε αυτό που κάνεις ή είναι κλειστό;

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Εφοσον την δουλεια την κανουν οι workers, για πιο λογο εχεις τα "task" στο main; Καντα ξεχωριστα προγραμματα ωστε το μοντςλο σου να τρχει σε διαφορετικα nodes. Ετσι και αλλιως εισαι πανω σε σοκετ.

Στην ουσία φτιάχνω ένα runtime. Ο χρήστης θα χρησιμοποιεί μέσα στον κώδικά του pragmas με tasks τα οποία καθορίζει ο ίδιος. Αυτά τα διαβάζει ο coordinator και τα βάζει σε ουρά. Οι workers ζητούν συνέχεια δουλειά από τον coordinator, ο οποιος και τη δίνει. Δε βάζω κατευθείαν τους workers να δουλεύουν σε shared ουρά για τους λόγους που είπα + τους μηχανισμούς συγχρονισμού. Επίσης χρησιμοποιώ sockets (socketpair(2)) για να έχω το μυαλό μου ήσυχο από άποψη αξιοπιστίας.

 

 

Ναι είναι γνωστές στο compile time. Καταλαβαίνω τί λες. Αλλά το γεγονός ότι το text segment είναι read-only δε με ενοχλεί. Αν πάει να γραφτεί κάτι εκεί, θα σκάσει το πρόγραμμα χωρίς να έχω silent corruption.

 

Σε C++ ήθελα να το ξεκινήσω. Έγραψα ένα προτότυπο σε C κι έμεινα εκεί.. Κλασσικό φαινόμενο. Λογικά μόλις τελειώσω και τη δουλειά αυτής της εβδομάδας θα το μεταφέρω.

 

Προς το παρόν είναι κλειστό.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Παντως "φωναζει" για αντικειμενοστρεφεια το app σου και C++.

Επισης θα πηγαινα με τη λυση του moukoublen σε datagram unix sockets που θα μεταφερουν data.

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ισχύει. Το βλέπω από τη στιγμή που ξεκίνησα το "προτότυπο"! :D Αλλά έλεγα άντε να κάνω κι αυτό και μετά ώστε να το σχεδιάσω καλά με OOP.

Δεν έχω εμπειρία με patterns για να το κάνω σίγουρα σωστά. Οπότε θέλω να αφιερώσω λίγο χρόνο στο σχεδιασμό.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Σιγουρα παντως ιδεες μπορεις να παρεις απο opensource projects που υλοποιουν τετοιες διεργασιες. Π.χ systemd-journald ή systemd-logind.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Στην ουσία φτιάχνω ένα runtime. Ο χρήστης θα χρησιμοποιεί μέσα στον κώδικά του pragmas με tasks τα οποία καθορίζει ο ίδιος. Αυτά τα διαβάζει ο coordinator και τα βάζει σε ουρά. Οι workers ζητούν συνέχεια δουλειά από τον coordinator, ο οποιος και τη δίνει. Δε βάζω κατευθείαν τους workers να δουλεύουν σε shared ουρά για τους λόγους που είπα + τους μηχανισμούς συγχρονισμού. Επίσης χρησιμοποιώ sockets (socketpair(2)) για να έχω το μυαλό μου ήσυχο από άποψη αξιοπιστίας.

 

Ναι είναι γνωστές στο compile time. Καταλαβαίνω τί λες. Αλλά το γεγονός ότι το text segment είναι read-only δε με ενοχλεί. Αν πάει να γραφτεί κάτι εκεί, θα σκάσει το πρόγραμμα χωρίς να έχω silent corruption.

 

Σε C++ ήθελα να το ξεκινήσω. Έγραψα ένα προτότυπο σε C κι έμεινα εκεί.. Κλασσικό φαινόμενο. Λογικά μόλις τελειώσω και τη δουλειά αυτής της εβδομάδας θα το μεταφέρω.

 

Προς το παρόν είναι κλειστό.

Μαλιστα. Στη θεση σου θα εβαζα python interpreter. Η λογικη λεει πως θα εχεις πολλα θεματα επειδη θες να κανεις την δουλεια του kernel. 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...