- •Методические рекомендации
- •План лекции
- •Интерфейс графического устройства
- •Программирование, основанное на ресурсах
- •Управления памятью
- •Документы и их представление
- •Контрольные вопросы
- •Редактирование функций.
- •Изучение работы приложения.
- •Самостоятельная работа.
- •Добавление своего класса.
- •Домашняя работа.
- •Лекция 2. Основы программирования. Работа с классом Вид. Методические рекомендации:
- •Интерфейс графического устройства
- •Работа с gdi объектами
- •Пример создания нового gdi объекта
- •Режимы преобразования координат
- •Режимы преобразования координат с постоянным масштабом
- •Режимы преобразования координат с переменным масштабом
- •Замечание
- •Координатные пространства mfc
- •Пример использования режимов преобразования координат
- •Работа с окнами, содержащими полосы прокрутки
- •Линейки прокрутки
- •Различные способы прокрутки
- •Прием ввода с клавиатуры
- •Контрольные вопросы
- •Обработка сообщений от мыши.
- •Задание для самостоятельной домашней разработки.
- •Лекция 3. Меню. Панели инструментов и строки состояния Методические рекомендации
- •Меню Windows
- •Обновление командного пользовательского интерфейса
- •Класс cMenu
- •Создание контекстных меню
- •Панели элементов управления и каркас приложений
- •Панель инструментов
- •Растровое изображение панели инструментов
- •Состояния кнопок Любая кнопка может находиться в следующих состояниях
- •Всплывающие подсказки
- •Строка состояния
- •Определение секций в строке состояния
- •Строка сообщений
- •Индикатор состояния
- •Управление строкой состояния
- •Контрольные вопросы:
- •Добавление переменных-членов.
- •Добавление функции OnMouseMove.
- •Программирование команд контекстного меню.
- •Программирование команд главного меню.
- •Домашняя работа.
- •Лекция 4. Диалоговые окна и стандартные элементы управления Методические рекомендации
- •Работа с модальным диалоговым окном
- •Стандартные элементы управления
- •Работа с немодальными диалоговыми окнами
- •Пользовательские сообщения
- •Принадлежность диалогового окна
- •Контрольные вопросы
- •Создание класса “диалогового окна”.
- •Добавление переменных-членов класса вашего диалогового окна.
- •Написание инициализирующего кода
- •Присваивание переменным начальных значений.
- •Самостоятельная работа.
- •Домашнее задание.
- •Лекция 5. Обработка сообщений Windows и программирование многопоточных приложений Методические рекомендации
- •Обработка сообщений в однопоточной программе
- •Передача управления
- •Таймеры
- •Обработка в периоды простоя
- •Программирование многопоточных приложений
- •Функция рабочего потока и запуск потока
- •Общение основного потока с рабочим
- •Общение рабочего потока с основным
- •Синхронизация потоков с использованием событий
- •Блокировка потоков
- •Критические секции
- •Потоки пользовательского интерфейса
- •Контрольные вопросы
- •Домашнее задание.
- •Задание для самостоятельной работы
- •Управление процессом Пример 1.
- •2. Замена образа процеса Пример 2. Использование функции exec.
- •Пример 3. Использование неименованного канала.
- •Пример 4. Создание именованного канал с именем "fifo".
- •3. Сигналы.
- •Пример 5. Использование сигналов.
- •Пример 6. Сообщения.
- •Пример 7. Сообщения.
- •Пример 8. Разделение памяти.
- •Пример 9. Использование семафоров.
- •Пример 10. Создание процесса вWindows.
- •Пример 11. Использование неименованного канала.
- •Пример 12. Использование именованного канала.
- •Пример 13. Использование разделяемой памяти File Mapping.
- •Пример 14. Использование Mailslot.
- •Пример 15. Использование событий.
Пример 8. Разделение памяти.
Процесс sh1, создаёт область разделяемой памяти размером 256 Кбайт и дважды присоединяет её к своему адресному пространству по разным виртуальным адресам. В "первую" область он записывает данные, а читает их из "второй" области. Процесс sh2, присоединяет ту же область (он получает только 32 Кбайта, таким образом, каждый процесс может использовать разный объем области разделяемой памяти). Он ждет момента, когда sh1 запишет в первое принадлежащее области слово любое отличное от нуля значение, и затем считывает данные из области. Sh1 делает "паузу", предоставляя sh2 возможность выполнения; когда sh1 принимает сигнал, он удаляет область разделяемой памяти из системы.
sh1.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define KEY 75
#define K 1024
void cleanup();
int shmid;
main()
{
int i, *pint;
for(i=1;i<23;i++)
signal(i,cleanup);
char *addr1, *addr2;
shmid = shmget(KEY,256*K,0777|IPC_CREAT);
addr1 = shmat(shmid,0,0);
addr2 = shmat(shmid,0,0);
printf("sh1:shmid=%d addr1=%x addr2=%x\n",shmid,addr1,addr2);
pint = (int *) addr1;
pint=getpid();pint++; /*Записать индекс sh1*/
for (i = 1; i<=5; i++)
*pint = i*2;
pint = (int *) addr2;
while (*pint!=0)
printf("sh1: адрес-%x\tзначение-%d\n",pint,*pint++);
pause();
}
void cleanup()
{
shmctl(shmid,IPC_RMID,0);
exit();
}
sh2.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define KEY 75
#define K 1024
int shmid;
main()
{
int i, *pint;
char *addr;
nice(39); /* уменьшение приоритета */
do
{
shmid = shmget(KEY,32*K,0777);
}
while(shmid<=0);
addr = shmat(shmid,0,0);
pint = (int *) addr;
printf("sh2: shmid=%d адрес=%x \n",shmid,addr);
while (*pint == 0);
while (*pint != 0)
printf("sh2: адрес-%x\tзначение-%d\n",pint,*pint++);
kill(*pint,1); /* Освобождение линии (hangup) */
}
Пример 9. Использование семафоров.
Два процесса sem1.out и sem2.out запускаются последовательно
sem1.out & , а когда sem1 «заснёт»
sem2.out
sem1 создаёт массив из трёх семафоров, во все функцией semctl заносится по единице и проверяется занесение. Подготавливается массив структур V для функции semop, со значениями 1 2 3 и флагом, позволяющим в случае завершения процесса восстановить значения семафоров. В нулевом семафоре массива формируется число 2, а затем функция semop проверяет этот семафор на 0, и так как он не 0, процесс «засыпает».
sem2 выполняет команду semop обнуляя нулевой семафор и заканчивает работу, при этом sem1 “просыпается“ выводит состояния семафоров, причём, в нулевом будет ноль, уничтожает массив семафоров и заканчивает работу.
Если после запуска sem1 выполнить команду shell ps, то можно увидеть спящий sem1.out.
sem1.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define KEY 75
int semid;
void cleanup();
struct sembuf p,v[3]; /* операции типа P и V */
main()
{
int i;
short initarray[3],outarray[3];
for (i = 0; i < 20; i++)
signal(i,cleanup);
semid = semget(KEY,3,0777 | IPC_CREAT);
initarray[0] = initarray[1] = initarray[2] = 1;
semctl(semid,3,SETALL,initarray);
semctl(semid,3,GETALL,outarray);
printf("sem:начальные значения семафоров %d %d %d\n", outarray[0], outarray[1], outarray[2]); /* 1 1 1 */
v[0].sem_num=0;
v[0].sem_op=1;
v[0].sem_flg=SEM_UNDO;
v[1].sem_num=1;
v[1].sem_op=2;
v[1].sem_flg=SEM_UNDO;
v[2].sem_num=2;
v[2].sem_op=3;
v[2].sem_flg=SEM_UNDO;
semop(semid,v,3);
semctl(semid,3,GETALL,outarray);
printf("sem: значения семафоров %d %d %d\n", outarray[0], outarray[1], outarray[2]); /* 2 3 4 */
p.sem_num=0;
p.sem_op=0;
p.sem_flg=SEM_UNDO;
semop(semid,&p,1);
// Здесь процесс засыпает и ждёт, пока значение семафора[0] не станет равным 0.
semctl(semid,3,GETALL,outarray);
printf("sem1: значения семафоров %d %d %d\n", outarray[0], outarray[1], outarray[2]); /* 0 3 4 */
cleanup()
}
cleanup()
{
semctl(semid,2,IPC_RMID,0);
exit();
}
sem2.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define KEY 75
int semid;
struct sembuf v; /* операция типа V */
main()
{
int i;
short outarray[3];
semid = semget(KEY,3,0777);
semctl(semid,3,GETALL,outarray);
printf("sem2: значения семафоров %d %d %d\n", outarray[0], outarray[1], outarray[2]); /* 2 3 4 */
v.sem_num=0;
v.sem_op=-2;
v.sem_flg=SEM_UNDO;
semop(semid,&v,1);
semctl(semid,3,GETALL,outarray);
printf("sem2: значения семафоров %d %d %d\n", outarray[0], outarray[1], outarray[2]); /* 2 3 4 */
p.sem_num=0;
p.sem_op=0;
p.sem_flg=SEM_UNDO;
semop(semid,&p,1);
}