Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Обучение VC++ / ЛекцииИнтернетС++ / Лекция_лаб_практикум.doc
Скачиваний:
64
Добавлен:
16.02.2016
Размер:
932.35 Кб
Скачать

Домашнее задание.

Модифицируйте данную программу таким образом, чтобы рабочие потоки общались с основным потоком через события по механизму, описанному в лекциях. Добавьте в каждый поток функциональность. Пусть первый поток ищет числа Фибоначи, а второй простые числа.

Задание для самостоятельной работы

В качестве самостоятельной работы предлагается студентам продемонстрировать умение использовать все системные механизы ОС Windows, перечисленные в примерах программ по теме и относящиеся к ОС Windows.

Во время сдачи работы студенту будет предложено выполнить задание на базе освоенного в лабораторной работе материала.

Управление процессом Пример 1.

Этой программе передаются два параметра - имя существующего файла и имя создаваемого файла. Процесс открывает существующий файл, создает новый файл и при условии отсутствия ошибок - порождает новый процесс.

#include <fcntl.h>

int fdrd, fdwt;

char c;

main(int argc,char *argv[])

{

if (argc != 3)

exit(1);

if ((fdrd = open(argv[1],O_RDONLY)) == -1)

exit(1);

if ((fdwt = creat(argv[2],0666)) == -1)

exit(1);

fork();

/*оба процесса исполняют одну и ту же программу*/

rdwrt();

exit(0);

}

rdwrt();

{

for(;;)

{

if (read(fdrd,&c,1) != 1)

return;

write(fdwt,&c,1);

} }

Ядро делает копию контекста родительского процесса для порожденного, при этом родительский процесс исполняется в одном адресном пространстве, а порожденный - в другом. Каждый из процессов может работать со своими собственными копиями глобальных переменных fdrd, fdwt и c, а также со своими собственными копиями стековых переменных argc и argv, но ни один из них не может обращаться к переменным другого процесса. Порожденный процесс наследует доступ к файлам родительского с правом использования тех же самых дескрипторов.

Родительский и порожденный процессы независимо друг от друга вызывают функцию rdwrt и в цикле считывают по одному байту информацию из исходного файла и переписывают ее в файл вывода. Функция rdwrt возвращает управление, когда при считывании обнаруживается конец файла. Дескрипторы fdrd в том и в другом процессах указывают на запись в таблице файлов, соответствующую исходному файлу, а дескрип­торы, подставляемые в качестве fdwt, - на запись, соответствующую результирующему файлу.

Ядро не гарантирует согласование темпов выполнения процессов и последовательность их запуска.

2. Замена образа процеса Пример 2. Использование функции exec.

sc

vi file_master.c

vi file_slave1.c

vi file_slave2.c

gcc file_master.c –o file_master

gcc file_slave1.c –o file_slave1

gcc file_slave2.c –o file_slave2

file_master 5 r 3 q

file_master.c

#include <stdio.h>

main(int iArg,char* cArg[])

{

int i;

if(fork()==0)

execl(“file_slave1”,“file_slave1”,cArg[1],cArg[2],0);

if(fork()==0)

execl(“file_slave2”,“file_slave2”,cArg[3],cArg[4],0);

wait((int*)0);

}

file_slave1.c

#include <stdio.h>

main(int iArg,char* cArg[])

{

int i;

for(i=1;i<=atoi(cAarg[1];i++)

{printf(“%s\n”,cArg[2]);sleep(3);}

}

file_slave2.c

#include <stdio.h>

main(int iArg,char* cArg[])

{

int i;

for(i=1;i<=atoi(cAarg[1];i++)

{printf(“%s\n”,cArg[2]);sleep(3);}

}

Пример 3. Использование неименованного канала.

Программа передаёт и считывает из канала строку символов "hello".

#include <stdio.h>

#include <unistd.h>

char string[]=”hello”;

main()

{

int i;

char buf[10];

int fds[2];

pipe (fds);

for(i=1;i<10;i++)

{

write(fds[1],buf,6);

read(fds[0],buf,6);

}

}