Радиотехника | Электротехника | Строительство | Растениеводство | Учёба | Книги | Фильмы | Игры | Вопросы-ответы | Визитка

Главы страницы

  1. Принцип работы программы
  2. Листинг программы
  3. Makefile
  4. Тест
  5. Эпилог

Учебные задания из старой практики

Учебный скрипт на С

Не знаю, стоит ли публиковать старые учебные задания. Если это кому-нибудь нужно можно написать сюда.

Работа семафоров на С

Это учебное задание одного из вузов

Листинг файла программы на С

;;; todo
/************************
 * Учебное задание #6
 * *********************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <signal.h>
#include <iostream>


void rwlock_create(const char *pathname,int proj_id,int mode){
    key_t key=ftok(pathname,proj_id);
    int semid=semget(key,3,IPC_CREAT|mode);
    unsigned short values[]={0,0,1};
    semctl(semid,0,SETALL,values);
}

int rwlock_open(const char *pathname,int proj_id){
    key_t key=ftok(pathname,proj_id);
    return semget(key,0,0);
}

void rwlock_rlock(int semid){
    struct sembuf ops[]={
        {.sem_num=0,.sem_op=0},
        {.sem_num=1,.sem_op=1}
    };
    semop(semid,ops,2);
}

void rwlock_wlock(int semid){
    struct sembuf ops[]={
        {.sem_num=0,.sem_op=1},
        {.sem_num=1,.sem_op=0},
        {.sem_num=2,.sem_op=-1}
    };
    semop(semid,ops,3);
}

void rwlock_runlock(int semid){
    struct sembuf ops[]={
        {.sem_num=1,.sem_op=-1}
    };
    semop(semid,ops,1);
}

void rwlock_wunlock(int semid){
    struct sembuf ops[]={
        {.sem_num=0,.sem_op=-1},
        {.sem_num=2,.sem_op=1}
    };
    semop(semid,ops,2);
}

void rwlock_destroy(const char *pathname,int proj_id){
    key_t key=ftok(pathname,proj_id);
    int semid=semget(key,0,0);
    semctl(semid,0,IPC_RMID);
}


int main(){
    rwlock_create("semkey",1,666);
    pid_t pid=fork();
    int n=0;
    if (pid==-1){
        perror("fork");
        return 1;
    }else if(!pid){
      int semid=rwlock_open("semkey",1);
      std::cout<<"nchild: pid="<<pid<<"  :  "<<semid<<"n"<<std::endl;
      rwlock_wlock(semid);
      while(n<5){
          ++n;
            for(int i=0;i<10;i++){
                putchar('C');
                fflush(stdout);
                usleep(10000);
            }
      }
      putchar('n');
      rwlock_wunlock(semid);
      rwlock_destroy("semkey",1);
      std::cout<<"child: Семафор удаленn"<<std::endl;
    }

    if(pid>0){    // the parent
      sleep(1);
      int semid=rwlock_open("semkey",1);
      std::cout<<"nthe parent: pid="<<pid<<"  :  "<<semid<<"n"<<std::endl;
      rwlock_wlock(semid);
      while(n<5){
        ++n;
        for(int i=0;i<10;i++){
//          m.lock();
            putchar('P');
            fflush(stdout);
//          m.unlock();
            usleep(10000);
        }
      }
      putchar('n');
      rwlock_wunlock(semid);

      sleep(3);
      rwlock_destroy("semkey",1);
      std::cout<<"the parent: Семафор удаленn"<<std::endl;
    }

}

Makefile

all:test

build:
	g++ -o lession7 -std=gnu++14 les7.cpp

test:build
	touch semkey
	./lession7
	rm semkey
        

Тест

$make

g++ -o lession7 -std=gnu++11 les7.cpp
touch semkey
./lession7

child: pid=0  :  393224

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
child: Семафор удален


the parent: pid=4614  :  -1

PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
the parent: Семафор удален

rm semkey


        

Эпилог

Функции программы документированы, переменные имеют доступные имена.

Но если понадобится помощь -- обращайтесь