cmultithreadingpthreadsstracefutex

pthread_mutex_lock and EAGAIN


I've use pthread for multithreded program and I've got the following situation. When I run the code without sleep command it causes error at run time, and when I add the sleep command program runs as expected.

With sleep:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <unistd.h>



pthread_mutex_t m_writer = PTHREAD_MUTEX_INITIALIZER;

void *print_str(void *args) {
  sleep(12);
  char *str = (char*) args;
  pthread_mutex_lock(&m_writer);
  printf("%s", str);
  pthread_mutex_unlock(&m_writer);
  pthread_exit(NULL);
}

int main(int argc, char **argv) {
  pthread_t t1;
  pthread_create(&t1, NULL, print_str, "Hello\n");
  pthread_mutex_lock(&m_writer);
  printf("LOL\n");
  pthread_mutex_unlock(&m_writer);
  pthread_join(t1, NULL);
  return 0;
}

Without sleep:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <unistd.h>



pthread_mutex_t m_writer = PTHREAD_MUTEX_INITIALIZER;

void *print_str(void *args) {
  char *str = (char*) args;
  pthread_mutex_lock(&m_writer);
  printf("%s", str);
  pthread_mutex_unlock(&m_writer);
  pthread_exit(NULL);
}

int main(int argc, char **argv) {
  pthread_t t1;
  pthread_create(&t1, NULL, print_str, "Hello\n");
  pthread_mutex_lock(&m_writer);
  printf("LOL\n");
  pthread_mutex_unlock(&m_writer);
  pthread_join(t1, NULL);
  return 0;
}

Error:

futex(0x559c3d3df0a0, FUTEX_WAIT_PRIVATE, 2, NULLHello ) = -1 EAGAIN (Resource temporarily unavailable)


Solution

  • strace shows results of system calls. Pthread functions in Linux are not system calls, they are libc functions implemented on top of (potentilally non-trivial) system calls. You are not interested in what internal system calls return. A single successfull call to ptread_mutex_lock may and sometimes does entail several failing syscalls.

    In particular, pthread_mutex_lock cannot possibly result in EAGAIN in this program because there are no attempts to lock the mutex recursively, and the default mutex is not recursive in Linux anyway. The FUTEX_WAIT_PRIVATE syscall that pthread_mutex_lock uses internally can and will result in EAGAIN. This is of no interest whatsoever to the application programmer.