Управление процессами и нитями в ОС QNX. Основные принципы управления процессами и нитями в ОС QNX, страница 8

Пример выполнения программы:

# make pthreads2

cc     pthreads2.c   -o pthreads2

# ./pthreads2

thread2:                1

thread2:                2

thread2:                3

thread2:                4

thread1:                1

Killed

Нить thread1 подает другой нити команду на завершение посредством сигнала и завершает весь процесс, поскольку PID у нитей и процесса общии.

pthread3.c

#include <pthread.h>

#include <signal.h>

pthread_t  t1, t2;

void* thread1( void* ptr)

{    

int i = 1;

while(i < 3)

{

sleep(5);

printf("thread1:\t\t%i\n", i++);

}

}

void* thread2( void* ptr)

{    

int i = 1;

while(i < 13)

{

sleep(1);

printf("thread2:\t\t%i\n", i++);

if(i==5) pthread_exit(NULL);

}

}

main()

{    

pthread_create(&t1, NULL, thread1, NULL);

pthread_create(&t2, NULL, thread2, NULL);

pthread_join(t1, NULL);

pthread_join(t2, NULL);

}

Пример выполнения программы:

# make pthreads3

cc     pthreads3.c   -o pthreads3

# ./pthreads3

thread2:                1

thread2:                2

thread2:                3

thread2:                4

thread1:                1

thread1:                2

Нить thread2 завершает свое выполнение, при этом нить thread1 продолжает выполняться.

2.5.  Порождение процессов в QNX.

Семейство функции spawn*() позволяет создавать и исполнять процесс, задаваемый путем path к испольняемому файлу. При этом в зависимости от значения аргумента mode:

-P_WAIT – процесс-родитель приостанавливает свое выполнение на время выполнения потомка.

-P_NOWAIT – процесс-родитель выполняется независимо от потомка.

-P_NOWAITO – аналогично P_NOWAIT, невозможно использовать wait().

-P_OVERLAY – потомок замещает место родителя в памяти.

spfather.c

#include <sys/types.h>

#include <stdlib.h>

#include <process.h>

main( int argc, char* argv[])

{    

char* arg[] = {"./spson", NULL};

int status;

switch(argv[1][0])

{

case '1':

spawnl(P_WAIT, "./spson","spson", NULL);

printf("father live\n");

break;

case '2':

spawnle(P_NOWAIT, "./spson","spson", NULL, NULL);

printf("father live\n");

break;

case '3':

spawnlp(P_NOWAITO, "./spson","spson", NULL);

printf("father live\n");

break;

case '4':

spawnv(P_OVERLAY, "./spson",arg);

printf("father live\n");

break;

}

wait(&status);   

printf("father is done\n");

}

spson.c

#include <stdlib.h>

main()

{

sleep(5);

printf("son is done\n");

}

spauto- скрипт для демонстрации вариантов.

#!/bin/ksh

make spfather

make spson

for i in 1 2 3 4

do

echo "./spfather $i"

./spfather $i

sleep 10

done   

Пример работы скрипта:

# ./spauto

cc     spfather.c   -o spfather

cc     spson.c   -o spson

./spfather 1

son is done

father live

father is done

./spfather 2

father live

son is done

father is done

./spfather 3

father live

father is done

son is done

./spfather 4

son is done

Если провести аналогии с POSIX-функциями, то spawn-семейство заменяет конструкцию fork() + exec[l,e,v,p](), расширенную дополнительными режимами. Так мы наблюдаем приостановку выполнения spfather на время работы spson в режиме P_WAIT, что соответствует введению в программу функции wait(). Режимы P_NOWAIT и P_NOWAITO аналогичны паре fork() + exec(). Режим P_OVERLAY – просто exec().

Примеры методов решения проблемы появления процессов-зомби.

spfather2.c

#include <sys/types.h>

#include <stdlib.h>

#include <process.h>

main( int argc, char* argv[])

{    

spawnl(P_NOWAIT, "./spson2","spson2", NULL);

sleep(5);

system(" pidin | grep Zombie");

}          

spfather3.c