Je sais que c'est une mauvaise idée! Certainement pour la programmation sûre la pile pour un fil donné devrait être considérée privée à ce fil. Mais POSIX garantit au moins que la totalité de la mémoire d'un thread est partagée et inscriptible par d'autres threads, ce qui signifie que la pile d'un thread peut (en théorie) être écrite par un autre thread. Donc je suis curieux de savoir comment on pourrait faire ça. La seule façon que je puisse penser serait de passer l'adresse d'une variable locale dans le fil B au thread A et A commencer à écrire dans cette zone générale. Mais cela n'émule pas complètement les appels de fonction en C. En particulier, je suis curieux de savoir si on peut dire, avoir thread A dormir tandis que son compteur de programme est mis à la première ligne de certaines fonctions qui prend des paramètres, puis sur le fil B Pousser réellement ces paramètres sur la pile, puis reprendre le fil A et le faire exécuter comme si la fonction était appelée à l'origine dans le fil A avec ces paramètres. Je pense que cela nécessite que le thread B puisse accéder aux registres du thread A sous des conventions d'appel au moins x86, et je ne suis pas sûr que ce soit possible.Comment écrire dans une pile de threads différente en C/C++?
Répondre
Il pourrait fonctionner pour passer un pointeur vers une volatile
variable locale en fonction foo()
dans le thread A à la fonction bar()
en fil B, puis laisser modifier fil B son contenu. Mais face à l'optimisation et à la mise en mémoire cache des threads, il n'y a aucun moyen de garantir que cela fonctionnera.
Donc, oui, c'est probablement une mauvaise idée. Pourquoi veux-tu faire cela? Serait sémaphores ou mutex être une meilleure solution?
Qu'est-ce que la "mise en mémoire cache des threads" et pourquoi l'optimisation serait-elle volatile? Le point de volatil est de ne pas être brisé par l'optimisation. –
J'ai lu que plusieurs threads s'exécutant sur plusieurs processeurs (ou processeurs multicœurs) ont des mémoires cache L1 différentes, ce qui peut interférer avec la sémantique 'volatile'. –
Il semble que vous essayiez d'implémenter votre propre mutex d'espace utilisateur (rapide), alors pourquoi ne pas explorer simplement en utilisant un futex? Ils can be tricky, mais au moins vous (en dernier recours) avez le noyau pour arbitrer les courses.
Ce qui Loadmaster suggéré pourrait fonctionner, avec deux threads. Plus de deux et ça va devenir très, très bizarre. De plus, je seconde ce qu'il a dit à propos des volatiles qui ne sont pas toujours volatiles.
Ok, une façon d'accéder à la pile de threads est d'allouer vous-même la mémoire de la pile et de l'assigner lors de la création du thread. Cela peut être réalisé par appel pthread_attr_setstack()
.
Les ensembles de codes suivants s'empilent dans la mémoire allouée manuellement (ici malloc) au lieu de l'allouer au système. Plus tard, vous pouvez accéder au pointeur mystack une fois le thread créé. Une utilisation de ce code est, vous pouvez prendre dump de la pile de thread pour prendre son snapshot et plus tard vous pouvez restaurer ce thread.
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <limits.h>
void *thread(void *arg) {
char *ret;
printf("thread() entered with argument '%s'\n", (char *)arg);
if ((ret = (char*) malloc(20)) == NULL) {
perror("malloc() error");
exit(2);
}
strcpy(ret, "This is a test");
pthread_exit(ret);
}
int main(void)
{
pthread_attr_t attr;
int rc;
pthread_t thid;
void *ret;
void *mystack;
size_t mystacksize = 2 * PTHREAD_STACK_MIN;
if (pthread_attr_init(&attr) == -1) {
exit(1);
}
/* Get a big enough stack and align it on 4K boundary. */
mystack = malloc(PTHREAD_STACK_MIN * 3);
if (mystack != NULL) {
printf("Using PTHREAD_STACK_MIN to align stackaddr %x.\n", mystack);
mystack = (void *)((((long)mystack + (PTHREAD_STACK_MIN - 1))/
PTHREAD_STACK_MIN) * PTHREAD_STACK_MIN);
} else {
exit(2);
}
printf("Setting stackaddr to %x\n", mystack);
printf("Setting stacksize to %x\n", mystacksize);
rc = pthread_attr_setstack(&attr, mystack, mystacksize);
if (rc != 0) {
printf("pthread_attr_setstack returned: %d\n", rc);
exit(3);
} else {
printf("Set stackaddr to %x\n", mystack);
printf("Set stacksize to %x\n", mystacksize);
}
if (pthread_create(&thid, &attr, thread, "thread 1") != 0) {
exit(1);
}
if (pthread_join(thid, &ret) != 0) {
exit(3);
}
printf("thread exited with '%s'\n", ret);
rc = pthread_attr_destroy(&attr);
if (rc != 0) {
exit(5);
}
exit(0);
}
Laissez-nous savoir si cela est ce que vous vouliez. Désolé pour la mauvaise indentation et le style de codage.
Doh, j'ai oublié que lorsque vous créez un autre thread, vous déterminez généralement l'espace utilisé pour sa pile. Cela rend les choses plus simples. Je suis toujours curieux de savoir s'il est possible de manipuler la pile utilisée pour les appels de fonction, ce qui AFAIK nécessite de changer les valeurs de registre d'un thread d'un autre thread. –
- 1. Comment écrire une trace de pile complète dans le journal?
- 2. Comment vérifier l'état actuel de la pile de threads
- 3. C# .net looping débordement de pile de threads
- 4. Comment supprimer cc, bcc dans MailComposerViewController?
- 5. Comment supprimer Cc ou Bcc dans MFMailIComposeViewController?
- 6. pile de noyau vs pile d'application en mode utilisateur
- 7. Configuration de boost :: taille de la pile de threads
- 8. Comment implémenter une pile générique en C#?
- 9. Comment rendre Zend_Navigation dans une section différente en XML?
- 10. Comment ajouter des vecteurs de longueur différente?
- 11. Comment utiliser dispatcherTimer.Stop dans une fonction différente?
- 12. Affecter une adresse IP différente pour différents threads dans un programme .net
- 13. Recherche de paramètres de début de threads en haut de la pile
- 14. en utilisant une table dans une classe différente
- 15. comment retourner une vue différente de la méthode différente dans le contrôleur dans MVC
- 16. Comment obtenir la pile de pile dans un appareil mobile?
- 17. Comment réutiliser une activité sur une pile
- 18. Debian cc flat_namespace
- 19. Comment écrire une araignée simple en Python?
- 20. Comment rouvrir une pile d'activités?
- 21. Terminer une activité précédente en pile de l'activité en cours?
- 22. Modifications dynamiques de la taille de la pile de threads dans Solaris 9?
- 23. PHP Mail, champ CC
- 24. Poussez une chaîne dans une pile?
- 25. Comment écrire une classe simple en C++?
- 26. Le nouveau thread dans ASP.NET s'exécute dans une culture différente
- 27. Comment DP et CC changent-ils dans Piet?
- 28. Comment ouvrir une fenêtre dans une session X11 différente?
- 29. Comment localiser une exception particulière dans une pile d'exception
- 30. Comment écrire une méthode générique en Java
Votre question sur l'écriture dans une pile de threads différente (facile) ou comment contrôler le déroulement d'un thread différent (difficile)? –
Je n'essaie pas de changer le flux d'exécution dans le thread A autre que quand il reprend en pensant qu'il a initialement appelé la fonction avec les paramètres fournis par B.Je ne considère pas, par exemple, comment B peut changer comment le thread A est une boucle ou une branche. –
Peut-être qu'une meilleure approche est simplement d'avoir A appeler la fonction au lieu de B? B peut toujours fournir les paramètres à A, en utilisant n'importe quel mécanisme de communication inter-thread que vous aimez. –