Учебные задания из старой практики
Не знаю, стоит ли публиковать старые учебные задания. Если это кому-нибудь нужно можно написать сюда.
Работа семафоров на С
Это учебное задание одного из вузов
Листинг файла программы на С
;;; 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
Эпилог
Функции программы документированы, переменные имеют доступные имена.
Но если понадобится помощь -- обращайтесь