sonicwave
sonicwave

Reputation: 6092

pthread_create fails with EAGAIN - but only on a certain function

I have a number of classes that register with a notification class in my program. On a particular incoming event, the notifier calls an update() function in each class. In two of these callee's I'm now trying to spawn a small helper thread which will wait a few seconds, then initialize some external hardware and return.

The helper threads are created with the PTHREAD_CREATE_DETACHED attribute, so I can avoid joining them.

This works fine for one of the threads (spawned from class1), but pthread_create() fails with EAGAIN in the other (from class2). According to the pthread_create() documentation, this happens if the application is out of resources. However, if I provide another incoming event, thread 1 can once again create its helper thread - while thread 2 still fails with the same error - and I can keep doing this with the same result.

The code I'm using is the same in both classes:

class class1_2 {
  public:
    void update();
  private:
    static void *init(void *self);
    pthread_t initThread;
    pthread_attr_t initThreadAttr;
}

void class1_2::update()
{
  printf("Class%d update()\n", classNumber);
  pthread_attr_setdetachstate(&initThreadAttr, PTHREAD_CREATE_DETACHED);
  int retval = pthread_create(&initThread, &initThreadAttr, init, this);
  printf("Class%d thread created = %d\n", classNumber, retval);
}

void *class1_2::init(void *self)
{
  printf("Class%d init()\n", self->classNumber);
  //wait 3 seconds, then do stuff (~1 additional second)
  return;
}

In gdb I get the following output:

<incoming event>

Class1 update()
[New thread 1]
Class1 thread created=0

Class2 update()
Class2 thread created=11 (EAGAIN)

Class1 init()
[Thread 1 exited]

<incoming event>

Class1 update()
[New thread 2]
Class1 thread created=0

Class2 update()
Class2 thread created=11 (EAGAIN)

Class1 init()
[Thread 2 exited]

(...and so it goes on)

I've tried commenting out the thread creation in class1 (which works) - but class2 still fails, prompting me to think there is a subtle difference between the classes. The shown code is the same in both classes though, so if anyone has a clue as to what other variables/functions/etc could have an influence, or what else could be going on, I'd be very happy to hear it.

Upvotes: 1

Views: 1129

Answers (2)

Jonathan Wakely
Jonathan Wakely

Reputation: 171303

For rep-whore purposes I'll promote my comment to an answer in case it's right ;)

Ensure you are calling pthread_attr_init to initialize the attribute object before you call pthread_attr_setdetachstate, and don't forget to destroy the attribute again too:

 void class1_2::update()
{
  printf("Class%d update()\n", classNumber);
  pthread_attr_init(&initThreadAttr);
  pthread_attr_setdetachstate(&initThreadAttr, PTHREAD_CREATE_DETACHED);
  int retval = pthread_create(&initThread, &initThreadAttr, init, this);
  printf("Class%d thread created = %d\n", classNumber, retval);
  pthread_attr_destroy(&initThreadAttr);
}

Upvotes: 1

sonicwave
sonicwave

Reputation: 6092

After a bit of tinkering I got it working. Instead of creating the threads in a detached state, I'm detaching them after creation with pthread_detach().

So, my update() has been changed to:

void class1_2::update()
{
  printf("Class%d update()\n", classNumber);
  int retval = pthread_create(&initThread, &initThreadAttr, init, this);
  printf("Class%d thread created = %d\n", classNumber, retval);
  retval = pthread_detach(initThread);
  printf("Class%d thread detached = %d\n", classNumber, retval);
}

If anyone has experienced something similar, or can otherwise shed some light on this, I'm still interested though.

Upvotes: 0

Related Questions