Комментарии к коду лабораторных по Unix.
Primary tabs
/* Это третье задание к 1-ой лабораторной - Отредактируйте prog1.c – отмените комментарии для блокировок файла (то что было закомментировано -см. в методичке)
. откомпилируйте файл заново. Собственно говоря - исходник дан преподавателем ,а наша задача состоит в том, чтобы разобраться с кодом.*/
#include <stdio.h> /* standard input/output header — стандартный заголовочный файл ввода/вывода */
#include <stdlib.h> /*stdlib.h — заголовочный файл стандартной библиотеки общего назначения языка Си, который содержит в себе функции, занимающиеся выделением памяти, контроль процесса выполнения программы, преобразования типов и другие*/
#include <unistd.h> /* определяет различные символьные константы и типы и объявляет некоторые функции. */
#include <sys/wait.h> /* заголовок определяет ряд символьных констант, используемых с waitpid()*/
#include <sys/file.h> /* определяет константы для операций с файлами */
#include <sys/stat.h> /* определяет структуру данных .возвращаемых функциями fstat(),lstat() и stat().*/
const char *filename = "messagebuf.dat"; /* указатель на область с именем файла. */
char msgbuf[64]; /* выделение памяти под символьный массив динной 64 байта */
void error_out(const char *msg) /* фукция которая не возвращает значения, но при этом получает указатель на неизменяемую символьную область.*/
{
perror(msg); /* выведет сообщение о последней ошибке, произошедшей во время выполнения функции или системного вызова + переданный, определяемый программистом параметр-сообщение, например - "Опять на работает !!!!!" */
exit(EXIT_FAILURE); /* ничего не возвращает, но требует параметр статуса выхода - любое число, соответсвующее коду ошибки, однако следует помнить, что наиболее безопасным является указание: 0 или EXIT_SUCCESSFUL при успехе и EXIT_FAILURE (не единица) при неудаче. */
}
void child(void)
{ /*With mandatory locks we block here until the parent unlocks the file. */
int fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0666 /*|S_ISGID */ ); /* устанавливает связь между файлом и его переменной-дискриптором. открывается с параметром который получается путём побитного сложения констант => обладает всеми их свойствами. подробнее см -http://pubs.opengroup.org/onlinepubs/009... третий аргумент определяет параметры*/
if (fd == -1) /* Если функция вернула -1 , то значит открыть файл не удалось. */
error_out("parent:open"); /* выводим сообщение о том, что открыть файл не удалось и описание последней произошедшей ошибки.*/
/* With advisory locks we block here until the parent unlocks the file.*/
int r = lockf(fd, F_LOCK, 0); /*Устанавливает POSIX-блокировку на открытом файле. F_LOCK - устанавливает блокировку на файле. Только один процесс может блокировать данный файл в текущий момент времени. Если файл уже блокирован, то он будет блокирован позже, когда будет снята предыдущая блокировка. */
if (r == -1) /* если блокировку установить не удалось выводим сообщение об этом деле. */
error_out("child:lockf"); /* */
/* Now we know the data is valid. - теперь мы знаем что данные доступны. */
int len = read(fd, msgbuf, sizeof(msgbuf)); /* */
if (len <= 0) /* */
error_out("client:read"); /* */
else
printf("child read: %s\n",msgbuf ); /* выводим сообщение о том, что потомок читает указаный файл. */
close(fd); /* преращаем работу с файлом */
}
void parent(int fd)
{
/* Read a message from console and write the message to the file. - читаем сообщение из консоли и выводим в файл. */
printf("Enter a message > "); /* */
scanf("%s", msgbuf); /* */
write(fd, msgbuf, sizeof(msgbuf)); /* */
/* Flush the user-space buffers to the filesystem before unlocking. - сливаем данные буфера в файл*/
fsync(fd); /* обеспечивает запись измененных данных в файл, заданный дескриптором - функция для асинхронной записи. */
/* As soon as the data on the filesystem is up-to-date we can unlock the file and let the child read it. - после того как в файловой системе обновлены мы можем разблокровать файл=> позволить процессу-потомку его прочитать.*/
int r = lockf(fd, F_ULOCK, 0); /* видимо. происходит открытие доступа к файлу, благодаря параметру F_ULOCK*/
if (r == -1) /* */
error_out("lockf:F_ULOCK"); /* сообщаем об ошибке если снять блокировку с файла не получилось.*/
close(fd); /* */
}
int main(int argc, char *argv[]) /* */
{
int status = 0; /* */
/* Create the file before the fork - до того как ветвится( дословно - форкнуться ) создаём файл .*/
int fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0666 /*|S_ISGID */ ); /* */
if (fd == -1) /* */
error_out("parent:open"); /* */
/* Put an exclusive lock on the file. - блокировка файла исклучительно для одного процесса. */
int r = lockf(fd, F_LOCK, 0); /* блокируем файл */
if (r == -1)
error_out("parent:lockf"); /*выводим сообщение об ошибке для случая если блокировка не удалась */
/* Now we fork with the file locked. - теперь мы создали новый процесс с заблокированным файлом. */
pid_t pid = fork(); /* */
switch (pid) /* проверяем значение которое получила данная переменная */
{
case -1: error_out("main:fork"); /* если это то выводим сообщение об ошибки*/
case 0: /* Run the child-only code. - запускаем код потомка - кстати, этот раздел выполнится только для родителя, потому что только в контектсте родителя fork вернёт значение "0" => потомок не сможет породить ещё одного потомка в данной ситуации.*/ /* */
child(); /* запускаем код потомка. */
exit(0); /* завершаем процессс-потомок. */
default: /* Run the parent-only code and wait for the child to finish. - здесь исполням только код родителя и ждём пока завершится потомок. */ /* */
parent(fd); /* запускаем код родителя*/
wait(&status); /* получает статус процесса-потомка. функция приостанавливает вызывающего блока до того момента пока не станет доступной статус-информация одного из завершившихся процессов-потомков данного процесса.*/
/* Child returns non-zero status on failure. */
printf("child status=%d\n", WEXITSTATUS(status)); /* */
}
unlink(filename); /* удаляем файловый дескриптор и сам файл. */
exit(0);/* перед завершением приложения функция вызывает ряд других функций. */
}
/* Ниже я сваливаю в кучу материал из интернета по поводу различных функций и вообще - непонятных вещей, которые имели место в программе */
/* */
/* Это третье задание к 1-ой лабораторной - Отредактируйте prog1.c – отмените комментарии для блокировок файла (то что было закомментировано -см. в методичке)
3. Редактируем child.c $ vi child.c
? удалить процедуру parent() ...
? заменить декларацию функции error_out() на extern void error_out(const char *msg);
? заменить тело main() на child(); return 0;
? сохранить файл
. откомпилируйте файл заново. Собственно говоря - исходник дан преподавателем ,а наша задача состоит в том, чтобы разобраться с кодом.*/
#include <stdio.h> /* standard input/output header — стандартный заголовочный файл ввода/вывода */
#include <stdlib.h> /*stdlib.h — заголовочный файл стандартной библиотеки общего назначения языка Си, который содержит в себе функции, занимающиеся выделением памяти, контроль процесса выполнения программы, преобразования типов и другие*/
#include <unistd.h> /* определяет различные символьные константы и типы и объявляет некоторые функции. */
#include <sys/wait.h> /* заголовок определяет ряд символьных констант, используемых с waitpid()*/
#include <sys/file.h> /* определяет константы для операций с файлами */
#include <sys/stat.h> /* определяет структуру данных .возвращаемых функциями fstat(),lstat() и stat().*/
const char *filename = "messagebuf.dat"; /* указатель на область с именем файла. */
char msgbuf[64]; /* выделение памяти под символьный массив динной 64 байта */
extern void error_out(const char *msg) /* фукция которая не возвращает значения, но при этом получает указатель на неизменяемую символьную область.*/
{
perror(msg); /* выведет сообщение о последней ошибке, произошедшей во время выполнения функции или системного вызова + переданный, определяемый программистом параметр-сообщение, например - "Опять на работает !!!!!" */
exit(EXIT_FAILURE); /* ничего не возвращает, но требует параметр статуса выхода - любое число, соответсвующее коду ошибки, однако следует помнить, что наиболее безопасным является указание: 0 или EXIT_SUCCESSFUL при успехе и EXIT_FAILURE (не единица) при неудаче. */
}
void child(void)
{ /*With mandatory locks we block here until the parent unlocks the file. */
int fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0666 /*|S_ISGID */ ); /* устанавливает связь между файлом и его переменной-дискриптором. открывается с параметром который получается путём побитного сложения констант => обладает всеми их свойствами. подробнее см -http://pubs.opengroup.org/onlinepubs/009... третий аргумент определяет параметры*/
if (fd == -1) /* Если функция вернула -1 , то значит открыть файл не удалось. */
error_out("parent:open"); /* выводим сообщение о том, что открыть файл не удалось и описание последней произошедшей ошибки.*/
/* With advisory locks we block here until the parent unlocks the file.*/
int r = lockf(fd, F_LOCK, 0); /*Устанавливает POSIX-блокировку на открытом файле. F_LOCK - устанавливает блокировку на файле. Только один процесс может блокировать данный файл в текущий момент времени. Если файл уже блокирован, то он будет блокирован позже, когда будет снята предыдущая блокировка. */
if (r == -1) /* если блокировку установить не удалось выводим сообщение об этом деле. */
error_out("child:lockf"); /* */
/* Now we know the data is valid. - теперь мы знаем что данные доступны. */
int len = read(fd, msgbuf, sizeof(msgbuf)); /* */
if (len <= 0) /* */
error_out("client:read"); /* */
else
printf("child read: %s\n",msgbuf ); /* выводим сообщение о том, что потомок читает указаный файл. */
close(fd); /* преращаем работу с файлом */
}
int main(int argc, char *argv[]) /* */
{
child();
return 0;
}
/* Это четвёртое задание к 1-ой лпбораторной - Разделим программу на две отдельных программы: parent.c и child.c и выполним в процессе потомке, порожденном
процессом parent, программу child. Для этого используется системный вызов execve.(см. методичку.)
Редактируем parent.c: $ vi parent.c
? удалить процедуру child() ...
? заменить декларацию функции error_out() на
? добавить в начале main декларацию extern void error_out(const char *msg);
? заменить в main() операции в case 0: на char *const env[] = {“PATH=.”, NULL};
? сохранить файл */
#include <stdio.h> /* standard input/output header — стандартный заголовочный файл ввода/вывода */
#include <stdlib.h> /*stdlib.h — заголовочный файл стандартной библиотеки общего назначения языка Си, который содержит в себе функции, занимающиеся выделением памяти, контроль процесса выполнения программы, преобразования типов и другие*/
#include <unistd.h> /* определяет различные символьные константы и типы и объявляет некоторые функции. */
#include <sys/wait.h> /* заголовок определяет ряд символьных констант, используемых с waitpid()*/
#include <sys/file.h> /* определяет константы для операций с файлами */
#include <sys/stat.h> /* определяет структуру данных .возвращаемых функциями fstat(),lstat() и stat().*/
const char *filename = "messagebuf.dat"; /* указатель на область с именем файла. */
char msgbuf[64]; /* выделение памяти под символьный массив динной 64 байта */
extern void error_out(const char *msg) /* заменить декларацию функции error_out() на extern void error_out(const char *msg);*/
{
perror(msg); /* выведет сообщение о последней ошибке, произошедшей во время выполнения функции или системного вызова + переданный, определяемый программистом параметр-сообщение, например - "Опять на работает !!!!!" */
exit(EXIT_FAILURE); /* ничего не возвращает, но требует параметр статуса выхода - любое число, соответсвующее коду ошибки, однако следует помнить, что наиболее безопасным является указание: 0 или EXIT_SUCCESSFUL при успехе и EXIT_FAILURE (не единица) при неудаче. */
}
/*здесь удалена процедура child*/
void parent(int fd)
{
/* Read a message from console and write the message to the file. - читаем сообщение из консоли и выводим в файл. */
printf("Enter a message > "); /* */
scanf("%s", msgbuf); /* */
write(fd, msgbuf, sizeof(msgbuf)); /* */
/* Flush the user-space buffers to the filesystem before unlocking. - сливаем данные буфера в файл*/
fsync(fd); /* обеспечивает запись измененных данных в файл, заданный дескриптором - функция для асинхронной записи. */
/* As soon as the data on the filesystem is up-to-date we can unlock the file and let the child read it. - после того как в файловой системе обновлены мы можем разблокровать файл=> позволить процессу-потомку его прочитать.*/
int r = lockf(fd, F_ULOCK, 0); /* видимо. происходит открытие доступа к файлу, благодаря параметру F_ULOCK*/
if (r == -1) /* */
error_out("lockf:F_ULOCK"); /* сообщаем об ошибке если снять блокировку с файла не получилось.*/
close(fd); /* */
}
int main(int argc, char *argv[]) /* */
{ char *const env[] = {"PATH=.", NULL};// этот массив констант добавлен для выполнения 4-ого задания - ".....добавить в начале main декларацию."
int status = 0; /* */
/* Create the file before the fork - до того как ветвится( дословно - форкнуться ) создаём файл .*/
int fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0666 /*|S_ISGID */ ); /* */
if (fd == -1) /* */
error_out("parent:open"); /* */
/* Put an exclusive lock on the file. - блокировка файла исклучительно для одного процесса. */
int r = lockf(fd, F_LOCK, 0); /* блокируем файл */
if (r == -1)
error_out("parent:lockf"); /*выводим сообщение об ошибке для случая если блокировка не удалась */
/* Now we fork with the file locked. - теперь мы создали новый процесс с заблокированным файлом. */
pid_t pid = fork(); /* */
switch (pid) /* проверяем значение которое получила данная переменная */
{
case -1: error_out("main:fork"); /* если это то выводим сообщение об ошибки*/
case 0: execve("./child", NULL, env); // запускает программу ,ссылка на файл исполняемого кода которой находится в списке параметров функции передаёт есй список переменных-строк и список переменных среды окружение - второй параметр.
default: /* Run the parent-only code and wait for the child to finish. - здесь исполням только код родителя и ждём пока завершится потомок. */ /* */
parent(fd); /* запускаем код родителя*/
wait(&status); /* получает статус процесса-потомка. функция приостанавливает вызывающего блока до того момента пока не станет доступной статус-информация одного из завершившихся процессов-потомков данного процесса.*/
/* Child returns non-zero status on failure. */
printf("child status=%d\n", WEXITSTATUS(status)); /* */
}
unlink(filename); /* удаляем файловый дескриптор и сам файл. */
exit(0);/* перед завершением приложения функция вызывает ряд других функций. */
}
/* Это третье задание к 1-ой лпбораторной - Отредактируйте prog1.c – отмените комментарии для блокировок файла (то что было закомментировано -см. в методичке)
. откомпилируйте файл заново. Собственно говоря - исходник дан преподавателем ,а наша задача состоит в том, чтобы разобраться с кодом.
4. Редактируем errmsg.c $ vi child.c
? удалить все функции, кроме error_out() ...
? сохранить файл :wq */
#include <stdio.h> /* standard input/output header — стандартный заголовочный файл ввода/вывода */
#include <stdlib.h> /*stdlib.h — заголовочный файл стандартной библиотеки общего назначения языка Си, который содержит в себе функции, занимающиеся выделением памяти, контроль процесса выполнения программы, преобразования типов и другие*/
#include <unistd.h> /* определяет различные символьные константы и типы и объявляет некоторые функции. */
#include <sys/wait.h> /* заголовок определяет ряд символьных констант, используемых с waitpid()*/
#include <sys/file.h> /* определяет константы для операций с файлами */
#include <sys/stat.h> /* определяет структуру данных .возвращаемых функциями fstat(),lstat() и stat().*/
const char *filename = "messagebuf.dat"; /* указатель на область с именем файла. */
char msgbuf[64]; /* выделение памяти под символьный массив динной 64 байта */
void error_out(const char *msg) /* фукция которая не возвращает значения, но при этом получает указатель на неизменяемую символьную область.*/
{
perror(msg); /* выведет сообщение о последней ошибке, произошедшей во время выполнения функции или системного вызова + переданный, определяемый программистом параметр-сообщение, например - "Опять на работает !!!!!" */
exit(EXIT_FAILURE); /* ничего не возвращает, но требует параметр статуса выхода - любое число, соответсвующее коду ошибки, однако следует помнить, что наиболее безопасным является указание: 0 или EXIT_SUCCESSFUL при успехе и EXIT_FAILURE (не единица) при неудаче. */
}
void child(void)
{ /*With mandatory locks we block here until the parent unlocks the file. */
int fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0666 /*|S_ISGID */ ); /* устанавливает связь между файлом и его переменной-дискриптором. открывается с параметром который получается путём побитного сложения констант => обладает всеми их свойствами. подробнее см -http://pubs.opengroup.org/onlinepubs/009... третий аргумент определяет параметры*/
if (fd == -1) /* Если функция вернула -1 , то значит открыть файл не удалось. */
error_out("parent:open"); /* выводим сообщение о том, что открыть файл не удалось и описание последней произошедшей ошибки.*/
/* With advisory locks we block here until the parent unlocks the file.*/
int r = lockf(fd, F_LOCK, 0); /*Устанавливает POSIX-блокировку на открытом файле. F_LOCK - устанавливает блокировку на файле. Только один процесс может блокировать данный файл в текущий момент времени. Если файл уже блокирован, то он будет блокирован позже, когда будет снята предыдущая блокировка. */
if (r == -1) /* если блокировку установить не удалось выводим сообщение об этом деле. */
error_out("child:lockf"); /* */
/* Now we know the data is valid. - теперь мы знаем что данные доступны. */
int len = read(fd, msgbuf, sizeof(msgbuf)); /* */
if (len <= 0) /* */
error_out("client:read"); /* */
else
printf("child read: %s\n",msgbuf ); /* выводим сообщение о том, что потомок читает указаный файл. */
close(fd); /* преращаем работу с файлом */
}
void parent(int fd)
{
/* Read a message from console and write the message to the file. - читаем сообщение из консоли и выводим в файл. */
printf("Enter a message > "); /* */
scanf("%s", msgbuf); /* */
write(fd, msgbuf, sizeof(msgbuf)); /* */
/* Flush the user-space buffers to the filesystem before unlocking. - сливаем данные буфера в файл*/
fsync(fd); /* обеспечивает запись измененных данных в файл, заданный дескриптором - функция для асинхронной записи. */
/* As soon as the data on the filesystem is up-to-date we can unlock the file and let the child read it. - после того как в файловой системе обновлены мы можем разблокровать файл=> позволить процессу-потомку его прочитать.*/
int r = lockf(fd, F_ULOCK, 0); /* видимо. происходит открытие доступа к файлу, благодаря параметру F_ULOCK*/
if (r == -1) /* */
error_out("lockf:F_ULOCK"); /* сообщаем об ошибке если снять блокировку с файла не получилось.*/
close(fd); /* */
}
int main(int argc, char *argv[]) /* */
{
int status = 0; /* */
/* Create the file before the fork - до того как ветвится( дословно - форкнуться ) создаём файл .*/
int fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0666 /*|S_ISGID */ ); /* */
if (fd == -1) /* */
error_out("parent:open"); /* */
/* Put an exclusive lock on the file. - блокировка файла исклучительно для одного процесса. */
int r = lockf(fd, F_LOCK, 0); /* блокируем файл */
if (r == -1)
error_out("parent:lockf"); /*выводим сообщение об ошибке для случая если блокировка не удалась */
/* Now we fork with the file locked. - теперь мы создали новый процесс с заблокированным файлом. */
pid_t pid = fork(); /* */
switch (pid) /* проверяем значение которое получила данная переменная */
{
case -1: error_out("main:fork"); /* если это то выводим сообщение об ошибки*/
case 0: /* Run the child-only code. - запускаем код потомка - кстати, этот раздел выполнится только для родителя, потому что только в контектсте родителя fork вернёт значение "0" => потомок не сможет породить ещё одного потомка в данной ситуации.*/ /* */
child(); /* запускаем код потомка. */
exit(0); /* завершаем процессс-потомок. */
default: /* Run the parent-only code and wait for the child to finish. - здесь исполням только код родителя и ждём пока завершится потомок. */ /* */
parent(fd); /* запускаем код родителя*/
wait(&status); /* получает статус процесса-потомка. функция приостанавливает вызывающего блока до того момента пока не станет доступной статус-информация одного из завершившихся процессов-потомков данного процесса.*/
/* Child returns non-zero status on failure. */
printf("child status=%d\n", WEXITSTATUS(status)); /* */
}
unlink(filename); /* удаляем файловый дескриптор и сам файл. */
exit(0);/* перед завершением приложения функция вызывает ряд других функций. */
}
Makefile =
CC=gcc PROGS=parent child CFLAGS=-Wall all: $(PROGS) child: child.c errmsg.o parent: parent.c errmsg.o $(CC) $(CFLAGS) parent.c errmsg.o -o parent errmsg.o: errmsg.c $(CC) $(CFLAGS) -c errmsg.c -o errmsg.o clean: rm -f *.o rm -f *.so rm -f *.a rm -f $(PROGS)
===============================это всё по первой лабе. конец 1-ой=============================
- Log in to post comments
- 27591 reads
Comments
tata_la
Fri, 09/09/2011 - 17:58
Permalink
вторая лаба
/* функция значение описание.*/ #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main() { pid_t pid; char *message; int n; printf("fork program starting\n"); // о порождении нового процесса. pid = fork(); switch(pid) { case -1: perror("fork failed"); exit(1); case 0: message = "This is the child"; /* Только потомок */ n = 15; break; default: message = "This is the parent"; /* Только родитель */ n = 10; break; } /* Общий код для родителя и потомка */ for(; n > 0; n--) { puts(message); /* Эта функция записывает выбранную строку string в стандартный поток вывода stdout, заменяя в выходном потоке нулевой символ окончания строки ('') символом новой строки ('n'). Функция puts возвращает последний записанный символ, кото- рым обычно является символ новой строки 'n'. Значение EOF свиде- тельствует об ошибке. См. также fputs, gets. */ sleep(1);// кратко - пристанавливае выполнение программы на указанное количество секунд. } exit(0); }===================это всё есть по второй.=========================
_________ _ _ ______
dthcbz фкн вгу and co
tata_la
Fri, 09/09/2011 - 21:37
Permalink
третья лаба
/*описание функции значение. */ /* здесь не будем использовать обновление контекста завершающего процеса, а просто пошлём завершаемому процессу сигналЮ, что позволит нам в дальнейшем узнать новый parent-pid потомка, после завершения родителя сигналом. */ #include <sys/types.h> #include <wait.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main(void) { pid_t child; char str[20]; if((child = fork()) < 0) /* если новый процесс породить не удалось */ { perror("fork"); exit(EXIT_FAILURE); } else if(child == 0) /* если удалось и это контекст процесса потомка (смотри принцип действия fork) */ { /* в процессе потомке — завершаем выполнение родителя */ printf("child is starting with pid = %d\n", getpid()); if ( kill(getppid(), SIGTERM)<0) { perror("kill:SIGTERM");} else { printf("parent is stoped know \n"); sleep(1); /* ждём, иначе может выйти так, что следуюяя команда выводящяя навый parent-pid выполнится раньше чем завершится радитель и потомок будет передан в наследники другому процессу - видимо, это связано с тем .что процесс выполняются параллельно -в смысле. что нельзя предсказать - какой из них закончится раньше */ printf("the new child's parent had pid= %d\n",getppid()); } } else /* */ { /* приостанавливаем выполнение процесса-родителя */ printf("parent is starting with pid = %d\n", getpid()); sleep(30); /* останавливаем выполнение не меньше чем столько вот секунд - но эта пауза будет прервана завершением, как видно из дальнейшего контекста - */ } exit(EXIT_FAILURE); /* не должны бы здесь оказаться */ }/* */ /* * pause() - приостанавливает выполнение программы до тех пор пока не будет получен сигнал ,который не приводит к завершеню программы и при этом не вызввает обработчик . */ #include <unistd.h> #include <stdlib.h> int main(void) { pause(); exit(EXIT_SUCCESS); } /* почему этот процесс нельзя завершить kill-ом по умолчанию. *//* */ /* * rmset.c — Удаление сигнала из набора */ #include <signal.h> #include <stdlib.h> #include <stdio.h> void err_quit(char *); int main(void) { sigset_t newset; /* Создать набор */ if((sigfillset(&newset)) < 0) err_quit("sigfillset"); /* Удалить SIGALRM из набора */ if((sigdelset(&newset, SIGALRM)) <0) err_quit("sigaddset"); /* SIGALRM не должен быть */ if(sigismember (&newset, SIGALRM)) puts("SIGALRM is in signal mask"); else puts("SIGALRM not in signal mask"); /* SIGTERM должен остаться в наборе */ if(sigismember(&newset, SIGTERM)) puts("SIGTERM in signal mask"); else puts("SIGTERM not in signal mask"); exit(EXIT_SUCCESS); } void err_quit(char *msg) { perror(msg); exit(EXIT_FAILURE); }/* */ #include <signal.h> #include <stdlib.h> #include <stdio.h> void err_quit(char *); int main(void) { sigset_t newset; /* создаем новый набор */ if((sigemptyset(&newset)) < 0) err_quit("sigemptyset"); /* Добавляем SIGTERM и SIGALRM */ if((sigaddset(&newset, SIGTERM)) < 0) err_quit("sigaddset:SIGTERM"); if((sigaddset(&newset, SIGALRM)) < 0) err_quit("sigaddset:SIGALRM"); /* Блокируем эти сигналы без их специальной обработки */ if((sigprocmask(SIG_BLOCK, &newset, NULL)) < 0) err_quit("sigprocmask"); /* Ожидаем сигнал */ pause(); exit(EXIT_SUCCESS); } void err_quit(char *msg) { perror(msg); exit(EXIT_FAILURE); } /*# # # # Откройте второе окно терминала (putty) и выполните команды: ps -al найдите процесс программы block - кстати, что это за ключ такой "-al" - отпишитесь если кто знает. kill -TERM $(pidof ./block) = с block ничего не происходит kill -ALRM $(pidof ./block) = с block ничего не происходит kill -QUIT $(pidof ./block) = а этот сигнал не блокируется и завершает процесс! *//*В POSIX-системах, SIGUSR1 и SIGUSR2 — пользовательские сигналы, которые могут быть использованы для межпроцессной синхронизации и управления. Системный вызов sigaction используется для изменения действий процесса при получении соответствующего сигнала. */ #include <unistd.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> void err_quit(char *); /* функция сообщения об ошибке */ void hndl_usr1(int); /* обработчик сигнала */ int main(void) { struct sigaction action; /* Устанавливаем обработчик сигнала */ action.sa_handler = hndl_usr1; sigemptyset(&action.sa_mask); action.sa_flags = SA_NOCLDSTOP; /* Регистрируем обработчик сигнала */ if((sigaction(SIGUSR1, &action, NULL)) < 0) err_quit("sigaction"); /* Достаточно времени, чтобы послать сигнал */ sleep(300); exit(EXIT_SUCCESS); } void err_quit(char *msg) { perror(msg); exit(EXIT_FAILURE); } void hndl_usr1(int signum) /* это функция-обработчик сигнала*/ { if(signum == SIGUSR1) puts("caught USR1"); else printf("caught %d\n", signum); // эта строчка по-моему не выполнится в даннос случае так как функция hndl_usr1() вызывается только в случае получения SIGUSR1 - если я не прав - просьба исправить) } /*Выполните в другом окне # ps -al # kill -USR1 $(pidof ./block) */============Конец третьей лабы =====================
_________ _ _ ______
dthcbz фкн вгу and co
tata_la
Sat, 09/10/2011 - 11:18
Permalink
5-ая лабораторная (перед ней можете разместить четвёртую)
=========================================
#include <unistd.h> int main(int argc, char *argv[]) { char buf; while (read(STDIN_FILENO, &buf, 1) > 0) write(STDOUT_FILENO, &buf, 1); } /*STDIN_FILENO определяет дескриптор файла для стандартного ввода, а STDOUT_FILENO - для стандартного вывода. */====================================
/*open/creat1 – открыть/создать файл с заданными опциями и режимом доступа int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); */ #include <unistd.h> #include <fcntl.h> int main(int argc, char *argv[]) { char buf; int fd_IN, fd_OUT; if (argc == 2) { fd_IN = open(argv[1], O_RDONLY, 0644); close(0); // закрываем стандартный ввод. dup(fd_IN);/* Теперь одинаково: стандартный ввод или ввод из файла ВОЗВРАЩАЕТСЯ НАИМЕНЬШИЙ ИЗ ДОСТУПНЫХ ДЕСКРИПТОРОВ, СООТВЕТСТВЕННО ЗДЕСЬ - 0 -то есть наш стандартный ввод.*/ } while (read(STDIN_FILENO, &buf, 1) > 0) write(STDOUT_FILENO, &buf, 1); } /* см. сюда - http://lord-n.narod.ru/download/books/wa... Вот простой пример использования аргумента командной строки. На экран выводятся слово Привет и ваше имя, которое надо указать в виде аргумента командной строки. #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { if(argc!=2) { printf("Вы забыли ввести свое имя.\n"); exit(1); } printf("Привет %s", argv[1]); return 0; } Если вы назвали эту программу name (имя) и ваше имя Том, то для запуска программы следует в командную строку ввести name Том. В результате выполнения программы на экране появится сообщение Привет, Том. */===========================
/*open/creat1 – открыть/создать файл с заданными опциями и режимом доступа int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); */ #include <unistd.h> #include <fcntl.h> int main(int argc, char *argv[]) { char buf; int fd_IN, fd_OUT; if (argc == 2) { fd_IN = open(argv[1], O_RDONLY, 0644); close(0); // закрываем стандартный ввод. dup(fd_IN);/* Теперь одинаково: стандартный ввод или ввод из файла ВОЗВРАЩАЕТСЯ НАИМЕНЬШИЙ ИЗ ДОСТУПНЫХ ДЕСКРИПТОРОВ, СООТВЕТСТВЕННО ЗДЕСЬ - 0 -то есть наш стандартный ввод.*/ } if (argc == 3) { fd_IN = open(argv[1], O_RDONLY, 0644); fd_OUT = open(argv[2], O_WRONLY, 0644); close(0); // закрываем стандартный ввод. dup(fd_IN);/* Теперь одинаково: стандартный ввод или ввод из файла ВОЗВРАЩАЕТСЯ НАИМЕНЬШИЙ ИЗ ДОСТУПНЫХ ДЕСКРИПТОРОВ, СООТВЕТСТВЕННО ЗДЕСЬ - 0 -то есть наш стандартный ввод.*/ close(1); // закрываем стандартный вывод. dup(fd_OUT); } while (read(STDIN_FILENO, &buf, 1) > 0) write(STDOUT_FILENO, &buf, 1); } /* см. сюда - http://lord-n.narod.ru/download/books/wa... Вот простой пример использования аргумента командной строки. На экран выводятся слово Привет и ваше имя, которое надо указать в виде аргумента командной строки. #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { if(argc!=2) { printf("Вы забыли ввести свое имя.\n"); exit(1); } printf("Привет %s", argv[1]); return 0; } Если вы назвали эту программу name (имя) и ваше имя Том, то для запуска программы следует в командную строку ввести name Том. В результате выполнения программы на экране появится сообщение Привет, Том. */================================
/* Два родственных процесса должны закрыть противоположные концы канала для использования оставшихся открытыми файловых дескрипторов для коммуникации в соответствующем направлении. */ #include <sys/wait.h> #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main(int argc, char *argv[]) { int pfd[2]; pid_t cpid; char buf; assert(argc == 2); /* проверка на сооответствие - если условие не выполнено -программа будет завершена.*/ if (pipe(pfd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } cpid = fork(); if (cpid == -1) { perror("fork"); exit(EXIT_FAILURE); } if (cpid == 0) { close(pfd[1]); /* Закрывает неиспользуемый write канала*/ puts("child is reading :");/* Потомок - читает из канала*/ while (read(pfd[0], &buf, 1) > 0) write(STDOUT_FILENO, &buf, 1); write(STDOUT_FILENO, "\n", 1); close(pfd[0]); /* закрывает второй конец кнала после использования*/ _exit(EXIT_SUCCESS); } else { /* Родитель – записывает argv[1] в канал */ close(pfd[0]); /* Закрывает неиспользуемый read канала */ printf("parent is writing = %s\n", argv[1]); /* Закрывает неиспользуемый read канала */ write(pfd[1], argv[1], strlen(argv[1])); /* Родитель – записывает argv[1] в канал */ close(pfd[1]); /* закрывает второй конец кнала после использования*/ /* читатель увидит EOF */ wait(NULL); /* ожидает завершения потомка */ exit(EXIT_SUCCESS); } } /* */======================это всё, что есть по 5-ой===========
_________ _ _ ______
dthcbz фкн вгу and co
tata_la
Sat, 09/10/2011 - 11:23
Permalink
6-ая лаба и комментарии к ней.
========================
/*ino_t st_ino; номер индексного узла для файла Синтаксис fstat #include <sys\stat.h> int fstat(char * handle, struct stat * buff) Функция fstat записывают информацию об открытом файле (или директории), связанным с дескриптором handle в структуру stat. Aргумент buff адресует структуру stat (определенную в файле sys\stat.h). */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> int get_inode (int fd) { struct stat buf; int ret; ret = fstat (fd, &buf); if (ret < 0) { perror ("fstat"); return -1; } return buf.st_ino; } int main (int argc, char *argv[]) { int fd, inode; if (argc < 2) { fprintf (stderr, "usage: %s <file>\n", argv[0]); return 1; } fd = open (argv[1], O_RDONLY); if (fd < 0) { perror ("open"); return 1; } inode = get_inode (fd); printf ("%d\n", inode); return 0; }================================
/*Проверьте работу следующей функции которая проверяет, располагается ли файл, указанный параметром fd на физическом диске (возвращает положительное целое) или на виртуальном, сетевом устройстве (возвращает 0). При ошибке, возвращает -1. */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> int is_on_physical_device (int fd) { int rez; struct stat sb; int ret; ret = fstat (fd, &sb); if (ret) { perror ("fstat"); return -1; } rez=gnu_dev_major (sb.st_dev); printf ("//////// %d\n", rez); return rez; } int main (int argc, char *argv[]) { int is_on_physical_device (int fd); int fd, ind; if (argc < 2) { fprintf (stderr, "usage: %s <file>\n", argv[0]); return 1; } fd = open (argv[1], O_RDONLY); if (fd < 0) { perror ("open"); return 1; } ind = is_on_physical_device (fd); if (ind == -1) puts ("При попытке определить место положения файла произошла ошибка (error here)"); if (ind == 0) puts ("Указанный вами файл располагается на виртуальном носителе. функуия проверки вернула ноль."); if (ind >0) printf ("Указанный вами файл %s\n располагается на физическом диске. функция проверки вернула %d\n", argv[1], ind); return 0; } /* http://manual.cream.org/index.cgi/gnu_de... #include _BSD_SOURCE #define <sys/types.h> dev_t makedev(int maj, int min); int major(dev_t dev); int minor(dev_t dev); Структура stat, объявленная в <sys\stat.h>, содержит следующие поля: struct stat { dev_t st_dev; устройство, на котором расположен файл ino_t st_ino; номер индексного узла для файла mode_t st_mode; тип файла и права доступа к нему nlink_t st_nlink; / счетчик числа жестких связей / uid_t st_uid; / идентификатор пользователя владельца / gid_t st_gid; / идентификатор группы владельца / dev_t st_rdev; / тип устройства для специальных файлов устройств / off_t st_size; / размер файла в байтах (если определен для данного типа файлов) / unsigbed long st_blksize; / размер блока для файловой системы / unsigned long st_blocks; / число выделенных блоков / time_t st_atime; / время последнего доступа к файлу / time_t st_mtime; /время последней модификации файла / time_t st_ctime; / время создания файла / */===================всё по 6-ой==================
_________ _ _ ______
dthcbz фкн вгу and co
tata_la
Sat, 09/10/2011 - 11:44
Permalink
7-ая
/* Создает и инциализирует сегмент общей памяти= Передача сообщений через очередь, рассмотренная в предыдущем параграфе, хотя и позволяет избежать использования ресурсов файловой системы, но требует копирования сообщений из буферов памяти в области пользователя в область ядра при записи, и обратно, при чтении. Разделяемая память позволяет наиболее эффективно обмениваться информацией различным процессам в системе, поскольку все процессы «присоединенные» к участку разделяемой памяти имеют прямой доступ для чтения и записи в этот участок. */ #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #include <stdlib.h> #define BUFSZ 4096 int main(void) { int shmid; if((shmid = shmget(IPC_PRIVATE, BUFSZ, 0666)) < 0) /*возвращающим идентификатор участка разделяемой памяти, указанного размера size в байтах и инициализирующим структуру данных ядра*/ { perror("shmget"); exit(EXIT_FAILURE); } printf("segment created: %d\n", shmid); system("ipcs -m"); /*передача параметра в качестве системной команды*/ exit(EXIT_SUCCESS); } /* ---------------- В реализации UNIX System V от AT&T2 в ядро системы были добавлены специальные средства для обеспечения коммуникации между процессами, выполняющимися на одной машине.3 Идея заключалась в использовании адресного пространства ядра, разделяемого между всеми процессами в системе, для построения структур данных и интерфейсов доступа к ним через специальные системные вызовы для взаимодействующих процессов. Такие средства получили название IPC4,это • очереди сообщений — для взаимодействия процессов через расширенный вариант FIFO структуры; • разделяемая память — для общего доступа к страницам памяти из разных процессов; • семафоры — средства синхронизации доступа к разделяемым ресурсам. ------------------------------ Создание любого IPC средства следует одной и той же логике: • поскольку средство должно быть доступно всем процессам, то оно представляется структурами данных ядра; • для уникальной идентификации ресурса он создается и подключается взаимодействующими процессами с помощью уникального ключа типа key_t, известного только взаимодействующим процессам и ядру; • все средства IPC имеют собственный уникальный идентификатор id, генерируемый ядром по заданному ключу при создании ресурса (системными вызовами msgget/2, shmget/2, semget/2) и используемый взаимодействующими процессами в других системных вызовах для обращения к ресурсу. */================
==============================
==========================
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/wait.h> void error_out(const char *msg) { perror(msg); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { int status; key_t mykey = 12345678; /* ключ для использования сегмента общей памяти */ const size_t region_size = sysconf(_SC_PAGE_SIZE); /* Используется сегмен в одну страницу */ /* Создание сегмента общей памяти */ int smid = shmget(mykey, region_size, IPC_CREAT | 0666); if (smid == -1) error_out("shmget"); /* Присоединение сегмента общей памяти */ void *ptr; ptr = shmat(smid, NULL, 0); /* Присоединение сегмента общей памяти */ if (ptr == (void *) -1) error_out("shmat"); pid_t pid = fork(); /* Порождение нового процесса */ if (pid == 0) {/* Процесс потомок наследует отображение памяти */ u_long *d = (u_long *) ptr; *d = 0xdeadbeef; /* потомок производи запись данных в сегмент */ exit(0); } else { /* Синхронизация с потомком через waitpid */ int status; waitpid(pid, &status, 0); /* Родитель использует значение из общей памяти */ printf("child wrote %#lx\n", *(u_long *) ptr); } /* По окончании, отсоединяем сегмент */ int r = shmdt(ptr); if (r == -1) error_out("shmdt"); /* Удаляем сегмент из ресурсов ядра */ r = shmctl(smid, IPC_RMID, NULL); if (r == -1) error_out("shmdt"); return 0; }============================
/* msgget - получает идентификатор очереди сообщений*/ #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int qid; /* Идентификатор очереди */ key_t key; /* Ключ очереди */ key = 123; if((qid == msgget(key, IPC_CREAT | 0666)) < 0) /* Создание очереди - Для создания или подключения к очереди сообщений используется вызов msgget/2 */ { perror("msgget:create"); exit(EXIT_FAILURE); } printf(" очередь создана - created queue id = %d\n", qid); if((qid == msgget(key, 0)) < 0) /* Открыть очередь еще раз */ { perror("msgget:open"); exit(EXIT_FAILURE); } printf("процесс открыл созданную ранее очередь - opened queue id = %d\n", qid); exit (EXIT_SUCCESS); }===============добавляйте материалы и заметки по 7-ой ниже==================
_________ _ _ ______
dthcbz фкн вгу and co
tata_la
Sat, 09/10/2011 - 11:47
Permalink
8-ая
/* int pthread_create (pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void*), void *restrict arg); где thread – уникальный идентификатор созданной нити, attr - атрибуты нити, (может быть NULL), start_routine – указатель на функцию для выполнения в данном потоке, arg- структура данных, определяющая параметр функции start_routine. ---------------------- pthread_t pthread_self(void); - этим вызовом нить может узнать свой собственный идентификатор. */ /* * C Code for fork() creation test */ #include <stdio.h> #include <stdlib.h> #define NFORKS 1000 void do_nothing() { int i; i= 0; } int main(int argc, char *argv[]) { int pid, j, status; for (j=0; j<NFORKS; j++) { /*** error handling ***/ if ((pid = fork()) < 0 ) { printf ("fork failed with error code= %d\n", pid); exit(0); } /*** this is the child of the fork ***/ else if (pid ==0) { do_nothing(); exit(0); } /*** this is the parent of the fork ***/ else { waitpid(pid, status, 0); } } } /* Кроме общего адресного пространства, нити используют еще следующие общие атрибуты контекста процесса, внутри которого они существуют: • идентификатор процесса PID и идентификатор родительского процесса PPID; • идентификаторы группы процесса и сеанса; • управляющий терминал; • права и владельцев процесса (UID и GID); • таблицу открытых файлов процесса; • записи блокировок файлов, порожденные fcntl/2; • диспозицию сигналов; • информацию о файловой системе: umask, домашний директорий и корневой директорий; • различные таймеры; • состояния семафоров IPC; • предельные значения для ресурсов; • время использования CPU (от times); • потребляемые ресурсы (от getusage); • значения приоритетов (от nice и setpriority); ------------------------------- Кроме указателя выполняемой инструкции (PC) и стека, каждая нить имеет собственные атрибуты (контекст нити): • идентификатор нити; • маску сигналов; • специальные данные нити; • альтернативный стек сигналов (см. sugaltstack/2); • переменную errno; • среду обработки операций с плавающей точкой (см. fenv/3); • политику и приоритет планировщика реального времени выполнения; • некоторые особенности, специфические для ОС Linux. */=========================
/* * FILE: threading.c * C Code for pthread_create() test ЧТОБЫ СКОМПИЛИРОВАТЬ = $ gcc -lpthread progname.c ///ЧТОБЫ ПОЛУЧИТЬ ИСПОЛНЯЕМЫЙ ФАЙЛ = $ gcc -lpthread -o progname.c */ #include <pthread.h> #include <stdio.h> #include <stdlib.h> #define NTHREADS 1000 void *do_nothing(void *null) { int i; i=0; pthread_exit(NULL); } int main(int argc, char *argv[]) { int rc, i, j, detachstate; pthread_t tid; /*идентификатор нити.*/ pthread_attr_t attr; /*Thread attributes record*/ pthread_attr_init(&attr); /* инициализирует объект с атрибутами нити.*/ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); /* Если поток создается неотделенным (PTHREAD_CREATE_JOINABLE), предполагается, что создающий поток будет ожидать его завершения и выполнять в созданном потоке pthread_join().*/ for (j=0; j<NTHREADS; j++) { rc = pthread_create(&tid, &attr, do_nothing, NULL); // создаём нить. if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } /* Wait for the thread */ rc = pthread_join(tid, NULL); // Функция nt pthread_join (pthread_t thread, void **status_addr); блокирует работу вызвавшей ее нити исполнения до завершения thread'а с идентификатором thread.- то есть мы ждём завершения каждой порождённой нити в главной нити мэйна if (rc) { printf("ERROR; return code from pthread_join() is %d\n", rc); exit(-1); } } pthread_attr_destroy(&attr); pthread_exit(NULL); }/****************************************************************************** * FILE: hello.c * DESCRIPTION: * A "hello world" Pthreads program. Demonstrates thread creation and * termination. * AUTHOR: Blaise Barney * LAST REVISED: 04/05/05 ******************************************************************************/ #include <pthread.h> #include <stdio.h> #include <stdlib.h> #define NUM_THREADS 5 void *PrintHello(void *threadid) { int tid; tid = (int)threadid; printf("Hello World! It's me, thread это нить номер #%d!\n", tid); pthread_exit(NULL); } int main(int argc, char *argv[]) { pthread_t threads[NUM_THREADS]; int rc, t; for(t=0;t<NUM_THREADS;t++) { printf(" Создаём нить In main: creating thread %d\n", t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } pthread_exit(NULL); }/****************************************************************************** * FILE: hello_arg1.c * DESCRIPTION: * A "hello world" Pthreads program which demonstrates one safe way * to pass arguments to threads during thread creation. * AUTHOR: Blaise Barney * LAST REVISED: 04/05/05 ******************************************************************************/ #include <pthread.h> #include <stdio.h> #include <stdlib.h> #define NUM_THREADS 8 char *messages[NUM_THREADS]; void *PrintHello(void *threadid) { int *id_ptr, taskid; sleep(1); id_ptr = (int *) threadid; taskid = *id_ptr; printf("Thread %d: %s\n", taskid, messages[taskid]); pthread_exit(NULL); } int main(int argc, char *argv[]) { 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] = "Klingon: Nuq neH!"; messages[4] = "German: Guten Tag, Welt!"; messages[5] = "Russian: Zdravstvytye, mir!"; messages[6] = "Japan: Sekai e konnichiwa!"; messages[7] = "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); }#include <pthread.h> #include <stdio.h> #define NTHREADS 4 #define N 1000 #define MEGEXTRA 1000000 #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdlib.h> pthread_attr_t attr; void *dowork(void *threadid) { double A[N][N]; int i,j,tid; size_t mystacksize; tid = (int)threadid; pthread_attr_getstacksize (&attr, &mystacksize); printf("Thread %d: stack size = %d bytes \n", tid, mystacksize); for (i=0; i<N; i++) for (j=0; j<N; j++) A[i][j] = ((i*j)/3.452) + (N-i); pthread_exit(NULL); } int main(int argc, char *argv[]) { pthread_t threads[NTHREADS]; size_t stacksize; int rc, t; pthread_attr_init(&attr); pthread_attr_getstacksize (&attr, &stacksize); printf("Default stack size = %d\n", (int) stacksize); stacksize = sizeof(double)*N*N+MEGEXTRA; // рассчитываем новый размер стека по формуле. printf("Amount of stack needed per thread = %d\n",(int)stacksize); pthread_attr_setstacksize (&attr, stacksize); printf("Creating threads with stack size = %d bytes\n",(int) stacksize); for(t=0; t<NTHREADS; t++) { rc = pthread_create(&threads[t], &attr, dowork, (void *)t); // порождаем нити в цикле. if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(EXIT_FAILURE); } } printf("Created %d threads.\n", t); pthread_exit(NULL); }_________ _ _ ______
dthcbz фкн вгу and co
tata_la
Sat, 09/10/2011 - 11:49
Permalink
и3 11=ой
С каждым сокет связываются три атрибута: домен, тип и протокол. Эти атрибуты задаются при создании сокета и остаются неизменными на протяжении всего времени его существования. Для создания сокета используется функция socket, имеющая следующий прототип.
_________ _ _ ______
dthcbz фкн вгу and co
tata_la
Sat, 09/10/2011 - 11:50
Permalink
и3 11=ой
/* * getname.c */ #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { char *host, **names, **addrs; struct hostent *hostinfo; /* В качетве параметра передается имя хоста, или используется текущий хост:*/ if(argc == 1) { char myname[256]; gethostname(myname, 255); host = myname; } else host = argv[1]; hostinfo = gethostbyname(host); if(!hostinfo) { fprintf(stderr, "cannot get info for host: %s\n", host); exit(1); } printf("results for host %s:\n", host); printf("Name: %s\n", hostinfo -> h_name); printf("Aliases:"); names = hostinfo -> h_aliases; while(*names) { printf(" %s", *names); names++; } printf("\n"); /* Может быть это не IP хост:*/ if(hostinfo -> h_addrtype != AF_INET) { fprintf(stderr, "not an IP host!\n"); exit(1); } /* Отобразить? IP адрес:*/ addrs = hostinfo -> h_addr_list; while(*addrs) { printf(" %s", inet_ntoa(*(struct in_addr *)*addrs)); addrs++; } printf("\n"); exit(0); }_________ _ _ ______
dthcbz фкн вгу and co
tata_la
Sat, 09/10/2011 - 11:53
Permalink
и3 11=ой
/* Создание очереди на соединение и игнорируется состояние потомка:*/ listen(server_sockfd, 5); signal(SIGCHLD, SIG_IGN); while(1) { char ch; printf("server waiting\n"); /* Принимаем запрос на соединение */ client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len); /* порождаем процесс потомок */ if(fork() == 0) { /* Потомок: обслуживаем запросы клиента по сокету client_sockfd с задержкой 5 сек*/ read(client_sockfd, &ch, 1); sleep(5); ch++; write(client_sockfd, &ch, 1); close(client_sockfd); exit(0); } /* Родитель: завершает работу с клиентом */ else { close(client_sockfd); } }_________ _ _ ______
dthcbz фкн вгу and co