J'apprends mutex actuellement et ce qui suit est le code de test. Cela fonctionne parfaitement bien. Il crée une autre instance une fois celle-ci terminée. Pourtant, il introduit également des frais généraux selon ici. Quelle est l'efficacité du verrouillage un mutex débloqué ? Quel est le coût d'un mutex ?. Comment puis-je modifier mon code pour améliorer l'efficacité ?

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

typedef struct _context_t {
  uint64_t id;
  char *name;
  bool initialized;
} context_t;

context_t *ctx = NULL;

context_t *get_instance() {
  pthread_mutex_lock(&lock);
  if (ctx == NULL) {
    ctx = (context_t *)malloc(sizeof(context_t));
    assert(ctx != NULL);
    ctx->initialized = false;
  }
  pthread_mutex_unlock(&lock);
  return ctx;
}

int id = 0;

void *do_work(void *arg) {
  context_t *ctx = get_instance();
  if (!ctx->initialized) {
    ctx->name = (char *)arg;
    ctx->id = ++id;
    ctx->initialized = true;
  }
  printf("name=%s\tid=%ld\n", ctx->name, ctx->id);
  return NULL;
}

int main() {
  int rc;
  pthread_t p1, p2;

  rc = pthread_create(&p1, NULL, do_work, "A");
  assert(rc == 0);
  rc = pthread_create(&p2, NULL, do_work, "B");
  assert(rc == 0);

  rc = pthread_join(p1, NULL);
  assert(rc == 0);
  rc = pthread_join(p2, NULL);
  assert(rc == 0);

  if (ctx) {
    free(ctx);
  }
  return 0;
}
c
0
user13851309 14 nov. 2020 à 04:00

1 réponse

Meilleure réponse

Au lieu d'avoir deux threads en course pour créer le context_t, vous devez le créer une fois avant le démarrage des threads et transmettre son adresse aux threads explicitement. Notez que vous pouvez passer plusieurs arguments via pthread_create() en les mettant dans une structure et en passant son adresse.

Ensuite, vous n'aurez pas du tout besoin d'un mutex, car les threads liront uniquement à partir de ctx plutôt que d'y écrire potentiellement.

2
John Zwinck 14 nov. 2020 à 01:16