Partage
  • Partager sur Facebook
  • Partager sur Twitter

Relancer un thread signal pthread_kill

    12 août 2021 à 4:35:49

    Bonjour.

    Je cherche a relancer un thread après l'avoir mis sur pause(). La seul technique que j'ai trouvé c'est signal qui me force a lancer une fonction dont je n'ai pas besoin. C'est moche :s

    Regardez :

    void sem_remove(Semaphore* sem){
        if(sem->next != NULL){
    
            //prevent leak memory
            SemaphoreQueue* buff;
            buff = sem->next;
            //get next thread
            sem->next = sem->next->next;
            //wakeup process
            pthread_kill(*buff->process, SIGUSR1);
            //released the node
            free(buff);
            //increment semaphore
            atomic_fetch_add(&sem->size, sem->cost);
        }else{
            //no queue so just increment semaphore
            atomic_fetch_add(&sem->size, sem->cost);
        }
    }
    void* lauchInstance(void* param){
        int* instanceId = (int *)param; // id of the instance
    
        printf("Instance %d created\n", *instanceId);
    
        if(sem_access(&mySemaphore, &myInstance[*instanceId], instanceId)){
            pause();
        }else{
            sleep(1);
        }
        signal(SIGUSR1, signal_handler);
        printf("Restart instance %d\n", *instanceId);
        printf("Instance %d just ending\n", *instanceId);
        sem_remove(&mySemaphore);
    
        pthread_exit (0);
    
    }


    Voyez comme la fonction

    void signal_handler(int sig);

    est complétement inutile.


    -
    Edité par -Crixus- 12 août 2021 à 4:36:14

    • Partager sur Facebook
    • Partager sur Twitter

    "Etre vrai, peu le peuvent."
    Friedrich Nietzsche

      12 août 2021 à 8:32:25

      Explique nous ce que tu souhaites faire précisément. Nous pourrons peut être t'apporter une solution plus adaptée.

      Par exemple si tu souhaites faire un modèle producer-consumer alors une condition variable sera probablement plus adaptée.

      • Partager sur Facebook
      • Partager sur Twitter

      git is great because Linus did it, mercurial is better because he didn't.

        12 août 2021 à 9:18:22

        Salut,

        Une idée simple, le main (l'appelant, le chef d'orchestre) fait un tableau d'une structure. Autant d'éléments que de threads.

        Dans cette structure évidemment toutes les paramètres pour le thread, mais aussi un bool "pause".

        Tu passes un pointeur vers une de ces structures en paramètre quand tu crées le thread, le main peut modifier le champs pause d'une de ces structures s'il le souhaite, et le thread le voit.

        • Partager sur Facebook
        • Partager sur Twitter

        Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

          12 août 2021 à 13:27:43

          Bonjour a vous. Merci pour l'interet.

          Il s'agit d'un sémaphore avec une queue. L'exercice est de simuler un certain nombre de programme qui se lancent et accèdent a une partie protégé du code. Si la partie est bloqué ils vont dans la queue. Quand un programme se termine, il réveille celui en tête de queue.

          Ce que j'ai fait est fonctionnel mais cette fonction de retour signal_handler(); (dans main) est inutile et m'énerve un peu...

          Si il ni a pas d'autre moyen ca m'ira... mais j'aurai aimé pouvoir gérer plutot du genre soit

          if(signal()){
            code de reprise;
          }

          (+ ou - l'équivalent mais mieux car j'ai accès aux variable... ici celle du thread lauchInstance qui me permet d'imprimer l'id de l'istance. Je n'y est pas accès dans la fonction signale_handler )

          ou directement :

          signal(); code de reprise

          (je reprend sans ajouter aucun code comme une interuption classique processeur)

          -------------------------------------------

          #ifndef SEMAPHORE_H
          #define SEMAPHORE_H
          
          #include <pthread.h>
          #include <stdatomic.h>
          #include <stdbool.h>
          
          typedef struct semaphoreQueue{
              pthread_t* process;
              struct semaphoreQueue* next;
          }SemaphoreQueue;
          
          typedef struct{
              SemaphoreQueue* next;
              volatile atomic_int size;
              int cost;
          }Semaphore;
          
          void sem_remove(Semaphore* sem);
          void sem_push(Semaphore* sem, pthread_t *thread);
          void sem_init(Semaphore* sem, int initSize, int initCost);
          bool sem_access(Semaphore* sem, pthread_t *thread, int* instanceId);
          
          #endif // SEMAPHORE_H
          
          #include "Semaphore.h"
          #include <signal.h>
          #include <unistd.h>
          #include <stdio.h>
          #include <stdlib.h>
          
          
          
          typedef atomic_flag mut_t;
          volatile mut_t mut = ATOMIC_FLAG_INIT; // false; true = locked; false = unlocked
          // void acquire(mut_t * m)
          #define acquire(m) while (atomic_flag_test_and_set(m))
          // void release(mut_t * m)
          #define release(m) atomic_flag_clear(m)
          
          void sem_remove(Semaphore* sem){
              if(sem->next != NULL){
          
                  //prevent leak memory
                  SemaphoreQueue* buff;
                  buff = sem->next;
                  //get next thread
                  sem->next = sem->next->next;
                  //wakeup process
                  pthread_kill(*buff->process, SIGUSR1);
                  //released the node
                  free(buff);
                  //increment semaphore
                  atomic_fetch_add(&sem->size, sem->cost);
              }else{
                  //no queue so just increment semaphore
                  atomic_fetch_add(&sem->size, sem->cost);
              }
          }
          
          void sem_push(Semaphore* sem, pthread_t *thread){
              // this is classic list algorithm
              SemaphoreQueue* toPush = (SemaphoreQueue*)malloc(sizeof(SemaphoreQueue));
              toPush->process = thread;
          
              if(sem->next == NULL){
                  sem->next = toPush;
              }else{
                  SemaphoreQueue* buffer = sem->next;
                  while(buffer->next != NULL){
                      buffer = buffer->next;
                  }
                  buffer->next = toPush;
              }
          }
          
          bool sem_access(Semaphore* sem, pthread_t *thread, int* instanceId){
          
              if(atomic_fetch_add(&sem->size, -sem->cost) - sem->cost < 0 ){
                  sem_push(sem, thread);
                  printf("Instance %d wait\n", *instanceId);
                  return true;
              }
              return false;
          }
          
          void sem_init(Semaphore* sem, int initSize, int initCost){
              sem->size = initSize;
              sem->cost = initCost;
          }
          
          
          #include <pthread.h>
          #include <stdbool.h>
          #include <stdio.h>
          #include <stdlib.h>
          #include <string.h>
          #include <stdatomic.h>
          #include <unistd.h>
          #include "Semaphore.h"
          #include <signal.h>
          
          #define MAX_RESOURCES 5
          int available_resources = MAX_RESOURCES;
          
          Semaphore mySemaphore;
          pthread_t myInstance[10];
          
          void signal_handler(int sig) {
              //printf("restart %d\n", sig);
          }
          
          void* lauchInstance(void* param){
              int* instanceId = (int *)param; // id of the instance
          
              printf("Instance %d created\n", *instanceId);
          
              if(sem_access(&mySemaphore, &myInstance[*instanceId], instanceId)){
                  pause();
              }else{
                  sleep(1);
              }
              signal(SIGUSR1, signal_handler);
              printf("Restart instance %d\n", *instanceId);
              printf("Instance %d just ending\n", *instanceId);
              sem_remove(&mySemaphore);
          
              pthread_exit (0);
          
          }
          
          int main(void) {
          
              sem_init(&mySemaphore, 4, 3); // initialize my semaphore
          
              pthread_attr_t attr;
              pthread_attr_init(&attr);
          
              for(int i = 0 ; i < 10 ; i++ ){
                  int* number = malloc(sizeof(int));
                  *number = i;
                  pthread_create(&myInstance[i], &attr, lauchInstance, number);
              }
          
              for(int i = 0 ; i < 10 ; i++ ){
                  pthread_join(myInstance[i], NULL);
              }
          
              return EXIT_SUCCESS;
          }
          





          -
          Edité par -Crixus- 12 août 2021 à 13:44:15

          • Partager sur Facebook
          • Partager sur Twitter

          "Etre vrai, peu le peuvent."
          Friedrich Nietzsche

          Relancer un thread signal pthread_kill

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown