【发布时间】:2020-12-03 17:57:17
【问题描述】:
我想让 n 个孩子在信号量的帮助下同步地在屏幕上打印不同的字母。我用一个孩子加上父母和两个信号量做了这件事,但我真的没有看到一种优雅的方式来推广到 n 个孩子。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <unistd.h>
#include <stdio.h>
union semun {
int val ;
struct semid_ds * buf ;
unsigned short * array ;
struct seminfo * __buf ;
} ;
int main(int argc, char const *argv[])
{
int idsem;
struct sembuf moins1sem1 [ 1 ] = { { 0, -1, 0 } } ;
struct sembuf plus1sem1 [ 1 ] = { { 0, 1, 0 } } ;
struct sembuf moins1sem2 [ 1 ] = { { 1, -1, 0 } } ;
struct sembuf plus1sem2 [ 1 ] = { { 1, 1, 0 } } ;
// key_t key = ftok("/etc/passwd",71);
// perror("Key");
idsem = semget(IPC_PRIVATE, 4, IPC_CREAT|IPC_EXCL| 0600); //IPC_CREATE creates key if doesn't exist an EXCL fails if key exists
//key is a "random" identifier for the sem and 1 is the nuber of sems we want to create
//Since we do not need to share the semaphore out of this process and its sons we can not use a key and instead provide the IPC_Private parameter
perror("idsem");
if(idsem == -1){
semget(IPC_PRIVATE,4,0); //If it didn't work w/ flags try w/o
perror("idsem2");
}
else{
union semun semopts;
semopts.val = 1; // We create an object to interact with the sem trough semctl
semctl(idsem,0,SETVAL,semopts);//we set the value (SETVAL) of the first (0) sem in the group of semaphore of id idsem to the value field of semopts
semopts.val = 0;
semctl(idsem,1,SETVAL,semopts);
}
switch (fork())
{
case 0:
for(int i=0;i<5;i++){
semop(idsem,moins1sem1,1);
fprintf(stderr,"Le fils dit A\n");
semop(idsem,plus1sem2,1);
}
break;
default:
for(int i=0;i<5;i++){
semop(idsem,moins1sem2,1);
fprintf(stderr,"Le pere dit B\n");
semop(idsem,plus1sem1,1);
}
break;
}
return 0;
}
我们的想法是有一种方法来生成 n sembuf 并且有一个函数只将第 n 个操作应用于给定的信号量
我试图在一个数组中定义所有的操作
struct sembuf oparray [ 4 ] = {{ 0, -1, 0 },{ 0, 1, 0 },{ 1, -1, 0 },{ 1, 1, 0 }} ;
并应用第 n 个操作
semop(idsem,oparray,n);
但它会将每个操作应用到 n 为止。
【问题讨论】:
-
semop(idsem,oparray,n);->semop(idsem,&oparray[n],1);? -
在这种情况下优雅是什么意思?