????3????????????
????semctl????????????????и???????????
????#include <sys/sem.h>
????int semctl (int semid?? int semnum?? int cmd?? /*???????*/ ) ;
??????????????????????????????????cmd??
????????semnum????????е????????????????
????????cmd???????10???????е???????semid??????????????????д????
????IPC_STAT   ????????????????????semid_ds????????洢??semun?е?buf?????С?
????IPC_SET     ??????????????????semid_ds?е????ipc_perm????????semun?е?buf??????
????IPC_RMID  ?????????????????????
????GETALL      ??????????????е???????????????
????GETNCNT  ???????????????????????
????GETPID      ???????????semop??????????PID??
????GETVAL      ????????????е????????????????????
????GETZCNT   ????????????????е??????????????
????SETALL       ????????????е????е???????????
????SETVAL      ????????????е????????????????????
?????? ????????????
????semget????????????????????????????????????????SETVAL????(???ü????е?????)??SETALL????(???ü????е??????) ????semctl????ɡ?
????SystemV???????????У???????????????????????????????κ?????????????????????????????????????????????semget????IPC_CREAT | IPC_EXCL???????????????????????????semget??????????????????????????y???????????????????
?????? ????
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/sem.h>
union semun
{
int val;
struct semid_ds *buf;
unsigned short *arry;
};
static int sem_id = 0;
static int set_semvalue();
static void del_semvalue();
static int semaphore_p();
static int semaphore_v();
int main(int argc?? char *argv[])
{
char message = 'X';
int i = 0;
/* ????????? */
sem_id = semget((key_t)1234?? 1?? 0666 | IPC_CREAT);
if(argc > 1)
{
/* ???????α???????????????? */
if(!set_semvalue())
{
fprintf(stderr?? "Failed to initialize semaphore ");
exit(EXIT_FAILURE);
}
/* ??????????????е?????????????????????? */
message = argv[1][0];
sleep(2);
}
for(i = 0; i < 10; ++i)
{
/* ????????? */
if(!semaphore_p())
{
exit(EXIT_FAILURE);
}
/* ?????????????? */
printf("%c"?? message);
/* ???????????????????????? */
fflush(stdout);
sleep(rand() % 3);
/* ????????????????????????? */
printf("%c"?? message);
fflush(stdout);
/* ?????????????????????????? */
if(!semaphore_v())
{
exit(EXIT_FAILURE);
}
sleep(rand() % 2);
}
sleep(10);
printf(" %d - finished "?? getpid());
if(argc > 1)
{
/* ????????????α?????????????????????? */
sleep(3);
del_semvalue();
}
exit(EXIT_SUCCESS);
}
static int set_semvalue()
{
/* ???????????????????????????????????? */
union semun sem_union;
sem_union.val = 1;
if(semctl(sem_id?? 0?? SETVAL?? sem_union) == -1)
{
return 0;
}
return 1;
}
static void del_semvalue()
{
/* ???????? */
union semun sem_union;
if(semctl(sem_id?? 0?? IPC_RMID?? sem_union) == -1)
{
fprintf(stderr?? "Failed to delete semaphore ");
}
}
static int semaphore_p()
{
/* ???????????1???????????P??sv??*/
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1;//P()
sem_b.sem_flg = SEM_UNDO;
if(semop(sem_id?? &sem_b?? 1) == -1)
{
fprintf(stderr?? "semaphore_p failed ");
return 0;
}
return 1;
}
static int semaphore_v()
{
/* ????????????????????????????????????????V??sv??*/
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1;//V()
sem_b.sem_flg = SEM_UNDO;
if(semop(sem_id?? &sem_b?? 1) == -1)
{
fprintf(stderr?? "semaphore_v failed ");
return 0;
}
return 1;
}
?????? ??????????????
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<errno.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#include<time.h>
#include<unistd.h>
#include<sys/wait.h>
#define MAX_SEMAPHORE 10
#define FILE_NAME "test2.c"
union semun{
int val ;
struct semid_ds *buf ;
unsigned short *array ;
struct seminfo *_buf ;
}arg;
struct semid_ds sembuf;
int main()
{
key_t key ;
int semid ??ret??i;
unsigned short buf[MAX_SEMAPHORE] ;
struct sembuf sb[MAX_SEMAPHORE] ;
pid_t pid ;
pid = fork() ;
if(pid < 0)
{
/* Create process Error! */
fprintf(stderr??"Create Process Error!:%s "??strerror(errno));
exit(1) ;
}
if(pid > 0)
{
/* in parent process !*/
key = ftok(FILE_NAME??'a') ;
if(key == -1)
{
/* in parent process*/
fprintf(stderr??"Error in ftok:%s! "??strerror(errno));
exit(1) ;
}
semid = semget(key??MAX_SEMAPHORE??IPC_CREAT|0666); //?????????????
if(semid == -1)
{
fprintf(stderr??"Error in semget:%s "??strerror(errno));
exit(1) ;
}
printf("Semaphore have been initialed successfully in parent process??ID is :%d "??semid);
sleep(2) ;
printf("parent wake up.... ");
/* ???????????????semaphore?????????semaphore????????????????????????????semaphore*/
/* ???????????????????semaphore 1 ??????????????μ????????*/
for(i=0;i<MAX_SEMAPHORE;++i)
{
sb[i].sem_num = i ;
sb[i].sem_op = -1 ; /*???????semaphore*/
sb[i].sem_flg = 0 ;
}
printf("parent is asking for resource... ");
ret = semop(semid ?? sb ??10); //p()
if(ret == 0)
{
printf("parent got the resource! ");
}
/* ???????????????? */
waitpid(pid??NULL??0);
printf("parent exiting .. ");
exit(0) ;
}
else
{
/* in child process! */
key = ftok(FILE_NAME??'a') ;
if(key == -1)
{
/* in child process*/
fprintf(stderr??"Error in ftok:%s! "??strerror(errno));
exit(1) ;
}
semid = semget(key??MAX_SEMAPHORE??IPC_CREAT|0666);
if(semid == -1)
{
fprintf(stderr??"Error in semget:%s "??strerror(errno));
exit(1) ;
}
printf("Semaphore have been initialed successfully in child process??ID is:%d "??semid);
for(i=0;i<MAX_SEMAPHORE;++i)
{
/* Initial semaphore */
buf[i] = i + 1;
}
arg.array = buf;
ret = semctl(semid ?? 0?? SETALL??arg);
if(ret == -1)
{
fprintf(stderr??"Error in semctl in child:%s! "??strerror(errno));
exit(1) ;
}
printf("In child ?? Semaphore Initailed! ");
/* ?????????????semaphore?????????semaphore*/
for(i=0;i<MAX_SEMAPHORE;++i)
{
sb[i].sem_num = i ;
sb[i].sem_op = -1 ;
sb[i].sem_flg = 0 ;
}
ret = semop(semid ?? sb ?? 10);//?????0??????
if( ret == -1 )
{
fprintf(stderr??"?????????semaphore????%s "??strerror(errno));
exit(1) ;
}
printf("child got semaphore??and start to sleep 3 seconds! ");
sleep(3) ;
printf("child wake up . ");
for(i=0;i < MAX_SEMAPHORE;++i)
{
sb[i].sem_num = i ;
sb[i].sem_op = +1 ;
sb[i].sem_flg = 0 ;
}
printf("child start to release the resource... ");
ret = semop(semid?? sb ??10) ;
if(ret == -1)
{
fprintf(stderr??"????????semaphore???:%s "??strerror(errno));
exit(1) ;
}
ret = semctl(semid ??0 ??IPC_RMID);
if(ret == -1)
{
fprintf(stderr??"semaphore??????:%s?? "??strerror(errno));
exit(1) ;
}
printf("child exiting successfully! ");
exit(0) ;
}
return 0;
}
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????