Единый процесс может «запускать на выполнение» несколько нитей, причем каждая из них представляет собой независимо выполняющийся поток управления со своим счетчиком команд, регистровым контекстом и стеком. Основные отличия процесса от нити заключаются в том, что, каждому процессу соответствует своя независимая от других область памяти, таблица открытых файлов, текущая директория и прочая информация, а у нитей одного процесса всё это общее, поскольку принадлежит одному единому процессу.
Создать нить можно следующим образом:
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 (в другом терминале)
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.