two threads in one process, or three threads in one process?

Hi community !!!

If I use this code:

void* thread1( void* not_used )
{

sleep(1);

return (EXIT_SUCCESS);
}

void* thread2( void* not_used )
{

sleep(1);

return (EXIT_SUCCESS);
}

int main( void )
{

pthread_create(NULL, NULL, thread1, NULL);
pthread_create(NULL, NULL, thread2, NULL);

sleep(20); 

return (EXIT_SUCCESS);
}

and I use pidin it shows 3 Threads with the same pid.
But I am creating only 2 Threads thread1 and thread2
does main create a Thread too?

If I want to have only two Threads, its enough to create one Thread with
pthread_create and the other one is generated from main?

or means pidin it is one Process with two threads inside with the same pid?

and another question why I have to use sleep(1) for rescheduling
in Threads and not in the equal programm using processes generated
by fork() where only one thread inside of both processes ?

whats the difference

Thank you

:unamused:

Yes. The only execution model in QNX is a thread; therefore you wouldn’t be able to execute pthread_create if you did not have a current execution context.

Sure.

Not sure what you mean here ?

You don’t have to use sleep(1) for rescheduling. There is only 1 scheduling entity in QNX and that is threads; any behaviour you see with a new thread created via fork (wrt scheduling), can be reproduced with a thread created via pthread_create().

Thank you rgallen but there is a difference

pid_t npid=0;
if(npid) {
for(i=0; i<10;i++)
printf( "prozess1\n);
return 0;
}
else
{
for (i=0; i<10; i++)
printf(“process2\n”);
return 0;
}

makes another output and sleep(1) is not needed for alternate output like

void* thread1 (void* not_used)
{
int i;
for(i=0; i<11; i++)
{
printf(“Thread2\n”);
//sleep(1);
}
return 0;
}

int main (void)
{
int i
pthread_create(NULL, NULL, thread1, NULL);

for (i=0; i<10; i++)
{
printf(“Thread1\n”);
//sleep(1);
}

sleep(20);

return 0;
}

with Threads it only works with sleep() or delay() ore something.

Thank you

What do you mean by “it only works”? What do you expect to see are what are you seeing?

Thank you mario !!

if I use this code:

#include <stdlib.h> /* EXIT_SUCESS, EXIT_FAILURE */
int main(void)
{
pid_t npid=0;

npid= fork();
if(npid) {
for (i=0;i<11;i++)
printf(“process1\n”);

		  return (EXIT_SUCCESS); 

}else{
for (i=0;i<11;i++)
printf(“process2\n”);

		 return (EXIT_SUCCESS);  
  }

return (EXIT_SUCCESS);
}

result in shell is :

process1
process2
process1
process2
process1
process2
process1
process2
process1
process2
process1
process2
process1
process2
process1
process2
process1
process2
process1
process2
process1
process2

if I use this code:

#include <stdlib.h> /* EXIT_SUCESS und EXIT_FAILURE */

void *thread2( void *not_used )
{
int i;

for ( i = 0; i < 11; i++ )
    {
    printf("thread2\n");
    sleep(1);
    }

return (EXIT_SUCCESS);
}

int main( void )
{
int i;

pthread_create(NULL, NULL, thread2, NULL);

for ( i = 0; i < 11; i++ )
    {
    printf("Thread1\n");
    sleep(1);
    }


sleep(20); 

return (EXIT_SUCCESS);
}

result in shell is:

thread2
Thread1
thread2
Thread1
thread2
Thread1
thread2
Thread1
thread2
Thread1
thread2
Thread1
thread2
Thread1
thread2
Thread1
thread2
Thread1
thread2
Thread1
thread2
Thread1


and If I use this code without sleep(1)

#include <stdlib.h> /* EXIT_SUCESS und EXIT_FAILURE */

void *thread2( void *not_used )
{
int i;

for ( i = 0; i < 11; i++ )
    {
    printf("thread2\n");
    }

return (EXIT_SUCCESS);
}

int main( void )
{
int i;
pthread_create(NULL, NULL, thread2, NULL);

for ( i = 0; i < 11; i++ )
    {
    printf("Thread1\n");
    }

    sleep(20); 

return (EXIT_SUCCESS);
}

result in shell is:

thread2
thread2
thread2
thread2
thread2
thread2
thread2
thread2
thread2
thread2
thread2
Thread1
Thread1
Thread1
Thread1
Thread1
Thread1
Thread1
Thread1
Thread1
Thread1
Thread1

and this is not equal with fork() and working with process
because there is no alternate.

only if i use sleep(1), or delay(1) with thread it will alternate.

so whats different by using Threads and using process to make
this conclusion.

with fork() I dont need sleep(1) or delay(1) to alternate.
and working with sleep(1) or delay(1) is reschedulingm I belief.

I hope you understand me!

Thank you !!!

:wink:

Yes, I think I understand what you’re asking.

First; there is no difference in the scheduling, however, there is a vast difference in what your 2 (so called) “equivalent” programs actually do.

The fork()ed program creates 2 stdio mutexes, whilst the threaded program creates only one.

The difference is that since you create an entirely new process “wrapper” around the thread when you use fork(), you implicitly create a new mutex for stdio.

In the threaded program, since both threads run inside the same process “wrapper”, there is, in fact, only 1 stdio mutex.

This means that in the threaded case, the thread that is waiting for the stdio mutex does not get it, until the other threads timeslice is exhausted (since that thread “immediately” reacquires the mutex it just released).

In the fork()ed case, since there is a separate stdio mutex, the other thread (inside the other process “wrapper”), acquires the it’s stdio mutex without contention; thus the alternation happens.

By putting sleep(1) in your threaded program you took the thread off the ready list (after releasing the mutex), thereby allowing the other thread to immediately acquire the mutex and execute its printf.

There is no mystery in here. The scheduling works exactly the same for a thread in a different process or within the same process, given that the programs are equivalent (which in this case they are not).

Granted you have to understand what’s going on under the covers (with stdio library etc.), but I think that goes without saying if you are trying to understand how the scheduler works.

Rennie

Thank you Rennie for the detailed explanation
this is very interesting for me !!!

:mrgreen:

With wrapper you mean the MMU?

and please explain me what means stdio mutual exclusion
I know mutex like this:

pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;

but I dont know an stdio mutex.
pleas explain me exactly what it is.

Thank you!! :wink:

By wrapper I mean process virtual address space.

The stdio mutex is created in libc (you don’t directly create it yourself). If there was no stdio mutex, then when you did a printf from 2 or more threads at the same time, you would most likely get intermingled output. In your example, the stdio mutex is locked on entry to printf, and unlocked on exit from printf.