Изучение основных принципов управления процессами и нитями в ОС LINUX, страница 8

Единый процесс может «запускать на выполнение» несколько нитей, причем каждая из них представляет собой независимо выполняющийся поток управления со своим счетчиком команд, регистровым контекстом и стеком. Основные отличия процесса от нити заключаются в том, что, каждому процессу соответствует своя независимая от других область памяти, таблица открытых файлов, текущая директория и прочая информация, а у нитей одного процесса всё это общее, поскольку принадлежит одному единому процессу.

Создать нить можно следующим образом:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void* (*start)(void *), void *arg)

Упрощенно вызов можно представить следующим образом:

pthread_create[&thr,NULL,start,NULL].

В таком случае создастся нить, которая начнет выполнять функцию start и запишет в переменную thr идентификатор созданной нити.

Ниже приведен текст программы, создающей 2 нити: первая печатает свое имя, а затем в цикле инкрементирует переменную времени, после чего засыпает на 5 секунд; вторая выполняет те же действия, но засыпает на 1 секунду.

#include <signal.h>

#include <pthread.h>

pthread_t t1, t2;

void thread1 (void)

{

int count=0;

int i;

printf("thread1 started\n");

for (i=0; i<2; i++)          {

      count=count+1;

      sleep(5);

      //dlya ydaleniya niti raskommentirovat

      printf("thread1: slept %d times\n", count);

      }

}

void thread2 (void)

{

int count=0;

int i;

printf("thread2 started\n");

system("ps -l");

for (i=0; i<10; i++)         {

      count=count+1;

      sleep(1);

      printf("thread2: slept %d times\n", count);

      }

}

main ()

{

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

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

pthread_join(t1, NULL);

pthread_join(t2, NULL);

}

Результаты.

$ ./two_threads.out

thread1 started

thread2 started

thread2: slept 1 times

thread2: slept 2 times

thread2: slept 3 times

thread2: slept 4 times

thread1: slept 1 times

thread2: slept 5 times

thread2: slept 6 times

thread2: slept 7 times

thread2: slept 8 times

thread2: slept 9 times

thread1: slept 2 times

thread2: slept 10 times

По результатам видно, что нити выполняются параллельно: пока вторая нить спит, первая выполняется и наоборот.

3.4.2. После запуска программы проанализируйте выполнение нитей, распределение во времени. Используйте для этого вывод таблицы процессов командой ps. Попробуйте удалить нить, зная ее идентификатор, командой kill. Приведите и объясните результат.

$ ./two_thr.out

thread1 started

thread2 started

       F S   UID        PID       PPID  C PRI  NI ADDR    SZ WCHAN TTY          TIME CMD

00000210 -   100    4861973    4280351  -  10   0    - 7512K -     ?        00:00:00 pterm

00000000 -   100    4997159    4861979  -  10   0    -  892K -     ?        00:00:00 two_thr.out

00000000 -   100    4997159    4861979  -  10   0    -  892K -     ?        00:00:00 two_thr.out

00000000 -   100    4997159    4861979  -  10   0    -  892K -     ?        00:00:00 two_thr.out

00000000 -   100    5001267    5001266  -  10   0    -  648K -     ?        00:00:00 ps

thread2: slept 1 times

thread2: slept 2 times

thread2: slept 3 times

thread2: slept 4 times

thread1: slept 1 times

thread2: slept 5 times

thread2: slept 6 times

thread2: slept 7 times

   $ kill 4997159 (в другом терминале)