Знакомство с функциями ОС Linux, относящимися к работе с потоками, страница 3

share...\n");

this_is_global=1000;

printf("Set this_is_global=%d\n",this_is_global);

pthread_create( &thread1, NULL, (void*)&thread_func, (void*) NULL);

pthread_create(&thread2, NULL, (void*)&thread_func, (void*) NULL);

pthread_join(thread1, NULL);

pthread_join(thread2, NULL);

printf("After threads, this_is_global=%d\n",this_is_global);

printf("\n");

printf("Now that the threads are done, let's call fork...\n");

local_main=17; this_is_global=17;

printf("Before fork(), local_main=%d, this_is_global=%d\n",local_main,

this_is_global);

pid=fork();

if (pid == 0) { /* this is the child */

printf("In child, pid %d: &global: 0x%X, &local: 0x%X\n", getpid(),

&this_is_global, &local_main);

local_main=13; this_is_global=23;

printf("Child set local main=%d, this_is_global=%d\n",local_main,

this_is_global);

exit(0);

}

else { /* this is parent */

printf("In parent, pid %d: &global: 0x%X, &local: 0x%X\n", getpid(),

&this_is_global, &local_main);

wait(&status);

printf("In parent, local_main=%d, this_is_global=%d\n",local_main,

this_is_global);

}

exit(0);

}

Результат работы программы:

First, we create two threads to see better what context they share...

Set this_is_global=1000

Thread 16386, pid 2900, addresses: &global: 0x8049C80, &local: 0x4099FAD0

In Thread 16386, incremented this_is_global=1001

Thread 32771, pid 2901, addresses: &global: 0x8049C80, &local: 0x4119FAD0

In Thread 32771, incremented this_is_global=1002

After threads, this_is_global=1002

Now that the threads are done, let's call fork...

Before fork(), local_main=17, this_is_global=17

In parent, pid 2898: &global: 0x8049C80, &local: 0xBFFFF634

In child, pid 2902: &global: 0x8049C80, &local: 0xBFFFF634

Child set local main=13, this_is_global=23

In parent, local_main=17, this_is_global=17

Пример 5. Передача аргументов потоку

#include <pthread.h>

#include <stdio.h>

#define NUM_THREADS 5

char *messages[NUM_THREADS];

void *PrintHello(void *threadid)

{

int *id_ptr, taskid;

sleep(1);

id_ptr = (int *) threadid;

taskid = *id_ptr;

printf("\n %s from thread %d \n", messages[taskid], taskid);

pthread_exit(NULL);

}

int main( )

{

pthread_t threads[NUM_THREADS];

int *taskids[NUM_THREADS];

int rc, t;

messages[0] = "English: Hello World!";

messages[1] = "French: Bonjour, le monde!";

messages[2] = "Spanish: Hola al mundo!";

messages[3] = "German: Guten Tag, Welt!";

messages[4] = "Latin: Orbis, te saluto!";

for(t=0;t<NUM_THREADS;t++)

{

taskids[t] = (int *) malloc(sizeof(int));

*taskids[t] = t;

printf("Creating thread %d\n", t);

rc = pthread_create(&threads[t], NULL, PrintHello, (void *) taskids[t]);

if (rc)

{

printf("ERROR; return code from pthread_create() is %d\n", rc);

exit(-1);

}

}

pthread_exit(NULL);

}

Результат работы программы:

Creating thread 0

Creating thread 1

Creating thread 2

Creating thread 3

Creating thread 4

English: Hello World! from thread 0

French: Bonjour, le monde! from thread 1

Spanish: Hola al mundo! from thread 2

German: Guten Tag, Welt! from thread 3

Latin: Orbis, te saluto! from thread 4

Пример 6. Использование глобальной переменной по записи

#include <stdio.h>

#include <pthread.h>

#include <stdlib.h>

int tot_items = 0 ;

struct kidrec {

int data ;

pthread_t id ; } ;

#define NKIDS 50

void *kidfunc(void *p)

{

int *ip = (int *)p ;

int tmp, n ;

tmp = tot_items ;

for (n = 0;n<50000;n++) tot_items = tmp + *ip ;

}

main ( )

{

struct kidrec kids[NKIDS] ;

int m ;

for (m=0; m<NKIDS; ++m)

{

kids[m].data = m+1 ;

pthread_create (&kids[m].id, NULL, kidfunc, &kids[m].data) ;

}

for (m=0; m<NKIDS; ++m) pthread_join (kids[m].id, NULL) ;

printf ("End of Program. Grand Total = %d\n", tot_items) ;

}

Задание на лабораторную работу:

Запустите несколько раз программу, приведенную в примере 6. Объясните письменно:

Результат работы программы.

Почему при запуске программы несколько раз получаются различные результаты?

Напишите программу, в которой главный поток создает дочерний поток, который в свою очередь создает потоки для распечатки чисел от 1 до 10. Количество создаваемых потоков передается аргументом из главного потока (функция main) и равно номеру бригады. Главный поток должен ждать окончания работы всех потоков.

Ответьте письменно: какие атрибуты потоков реализованы в библиотеке Pthreads

(см. <pthread.h> и man pages).

Содержание отчета по лабораторной работе:

Текст и результат работы программы.

Ответы на вопросы.

Вывод.

Сорокин Н.Ю., 2004г., http://evm.khstu.ru/os/lab04.html