我必须创建一个程序来同步两个进程,每个进程只打印一个字母,这样每当我们观察程序的输出时,“A”
和 之间的差异“B”
不大于 2。
所以这会被接受:
BAABBAABBABA
这不会是因为它打印了 4 个 B 而只打印了 2 个 A:
ABBABB
所以对于初学者,我决定使用 POSIX 信号量。
我创建了两个信号量,使用 sem_open
给它们所有权限
然后我创建了两个子进程,对于每个子进程,我打开我创建的信号量,如 sem_open
的手册页中所述并操作它们。
我不认为是 sem_post
和 sem_wait
的逻辑出了问题,因为程序似乎忽略了它们。
所以我的问题是。出了什么问题?
编辑:我真的不需要问题的解决方案。仅提供一些指导将不胜感激并欢迎作为答案。提前致谢!
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <semaphore.h>
int main(void){
sem_t *semA = sem_open("/semA", O_CREAT|O_EXCL, S_IRWXU | S_IRWXG | S_IRWXO, 0); //Initialize semaphore(= 0) for process A
sem_t *semB = sem_open("/semB", O_CREAT|O_EXCL, S_IRWXU | S_IRWXG | S_IRWXO, 0); //Initialize semaphore(= 0) for process B
if (fork()){ // parent process
if(fork()){}
else{
sem_t *childsemA = sem_open("/semA", 0);
sem_t *childsemB = sem_open("/semB", 0);
while(1){
printf("A");
sem_post(childsemB);
sem_wait(childsemA);
}
}
}
else{
sem_t *childsemA = sem_open("/semA", 0);
sem_t *childsemB = sem_open("/semB", 0);
while(1){
printf("B"); // child2 process
sem_post(childsemA);
sem_wait(childsemB);
}
}
return 0;
}
输出:
最佳答案
我可以建议您使用 System V 信号量吗?这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/sem.h>
#include "Semaphores.h"
#define SEM1_KEY (key_t)888
#define SEM2_KEY (key_t)1234
int sem1, sem2;
int main()
{
pid_t pid;
sem1 = semget(SEM1_KEY, 1, IPC_CREAT | 0666);
if(sem1 < 0)
{
fprintf(stderr, "\nSEMGET Failed\n");
exit(EXIT_FAILURE);
}
sem2 = semget(SEM2_KEY, 1, IPC_CREAT | 0666);
if(sem1 < 0)
{
fprintf(stderr, "\nSEMGET Failed\n");
exit(EXIT_FAILURE);
}
SEM_SET(sem1, 1);
SEM_SET(sem2, 0);
if((pid = fork()) == -1)
{
fprintf(stderr, "\nError in fork()\n");
exit(EXIT_FAILURE);
}
if(pid == 0)
{
while(1)
{
SEM_WAIT(sem2);
printf("%c", 'B');
fflush(stdout);
sleep(1);
SEM_POST(sem1);
}
}
while(1)
{
SEM_WAIT(sem1);
printf("%c", 'A');
fflush(stdout);
sleep(1);
SEM_POST(sem2);
}
wait(0);
SEM_DEL(sem1);
SEM_DEL(sem2);
exit(EXIT_SUCCESS);
}
这是包含 System V 信号量实现的头文件 Semaphores.h:
#include <sys/sem.h>
union semun
{
int val;
struct semid_ds * buf;
unsigned short * array;
};
int SEM_SET(int sem_id, int sem_val)
{
union semun sem_union;
sem_union.val = sem_val;
return semctl(sem_id, 0, SETVAL, sem_union);
}
int SEM_DEL(int sem_id)
{
return semctl(sem_id, 0, IPC_RMID);
}
int SEM_WAIT(int sem_id)
{
struct sembuf sem_buf;
sem_buf.sem_num = 0;
sem_buf.sem_op = -1;
sem_buf.sem_flg = SEM_UNDO;
return semop(sem_id, &sem_buf, 1);
}
int SEM_POST(int sem_id)
{
struct sembuf sem_buf;
sem_buf.sem_num = 0;
sem_buf.sem_op = 1;
sem_buf.sem_flg = SEM_UNDO;
return semop(sem_id, &sem_buf, 1);
}
结果是这样的:
ABABABABABABABABA and so on
fflush()
可能是问题所在,但您的代码有一些泄漏,您需要了解什么是临界区,并且需要检查 fork() 的返回值。
关于c - 在c中用信号量同步两个子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54136645/