C 与system-v信号量的父子同步
我有一个函数,可以在循环中逐字符打印某些内容。我想做的是同步父进程和子进程,这样每个进程都可以打印一行,而不受另一个进程的干扰。我试着用信号量来做这件事 这是我的代码:C 与system-v信号量的父子同步,c,ipc,semaphore,C,Ipc,Semaphore,我有一个函数,可以在循环中逐字符打印某些内容。我想做的是同步父进程和子进程,这样每个进程都可以打印一行,而不受另一个进程的干扰。我试着用信号量来做这件事 这是我的代码: int main() { int i, sem; struct sembuf u = {0, 1, 0}; struct sembuf d = {0 -1, 0}; sem = semget(IPC_PRIVATE, 1, 0600); semctl(sem, 0, SETV
int main() {
int i, sem;
struct sembuf u = {0, 1, 0};
struct sembuf d = {0 -1, 0};
sem = semget(IPC_PRIVATE, 1, 0600);
semctl(sem, 0, SETVAL, 1);
if (!fork()) {
for (i=0;i<10;i++){
semop(sem, &d, 1)) < 0)
print_char_by_char("hello\n");
semop(sem, &u, 1);
}
} else {
for (i=0;i<10;i++){
semop(sem, &d, 1);
print_char_by_char("world\n");
semop(sem, &u, 1);
}
semctl(sem, 0, IPC_RMID);
}
return 0;
}
我得到了semop:文件太大
根据
EFBIG:对于某些操作,sem_num的值小于0或
大于或等于集合中的信号量数量
然后,在不知道您的print\u char\u by\u char
函数如何运行的情况下,我们无法知道为什么会出现乱码打印(请记住printf
和其他缓冲区,因此您应该使用fflush
下一步,或者直接使用write
)
顺便说一句,我试图执行您的代码(我在下面写的),如果我删除
semctl(sem, 0, IPC_RMID);
这可能是您放错了位置(应该在返回之前进行,否则首先完成的将删除信号量集,我猜)
代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/sem.h>
void error_handler(const char *msg)
{
perror(msg);
exit(EXIT_FAILURE);
}
int main(int argc, const char **argv)
{
if (argc != 1)
{
fprintf(stderr, "Usage: %s <no arguments>\n", argv[0]);
return EXIT_FAILURE;
}
int i, sem;
struct sembuf u = {0, 1, 0};
struct sembuf d = {0, -1, 0};
sem = semget(IPC_PRIVATE, 1, 0600);
semctl(sem, 0, SETVAL, 1);
if (!fork())
{
for (i = 0; i < 10; i++)
{
if (semop(sem, &d, 1) == -1)
error_handler("main | semop [d - father]\n");
if (write(STDOUT_FILENO, "hello\n", 7) == -1)
error_handler("main | write [hello]\n");
if (semop(sem, &u, 1) == -1)
error_handler("main | semop [u - father]\n");
}
} else {
for (i = 0; i < 10; i++)
{
if (semop(sem, &d, 1) == -1)
error_handler("main | semop [d - child]\n");
if (write(STDOUT_FILENO, "world\n", 7) == -1)
error_handler("main | write [world]\n");
if (semop(sem, &u, 1) == -1)
error_handler("main | semop [u - child]\n");
}
// semctl(sem, 0, IPC_RMID);
}
return EXIT_SUCCESS;
}
相反,如果您想同步父子关系中的两个进程(这听起来很奇怪…),我建议您根据
EFBIG:对于某些操作,sem_num的值小于0或
大于或等于集合中的信号量数量
然后,在不知道您的print\u char\u by\u char
函数如何运行的情况下,我们无法知道为什么会出现乱码打印(请记住printf
和其他缓冲区,因此您应该使用fflush
下一步,或者直接使用write
)
顺便说一句,我试图执行您的代码(我在下面写的),如果我删除
semctl(sem, 0, IPC_RMID);
这可能是您放错了位置(应该在返回之前进行,否则首先完成的将删除信号量集,我猜)
代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/sem.h>
void error_handler(const char *msg)
{
perror(msg);
exit(EXIT_FAILURE);
}
int main(int argc, const char **argv)
{
if (argc != 1)
{
fprintf(stderr, "Usage: %s <no arguments>\n", argv[0]);
return EXIT_FAILURE;
}
int i, sem;
struct sembuf u = {0, 1, 0};
struct sembuf d = {0, -1, 0};
sem = semget(IPC_PRIVATE, 1, 0600);
semctl(sem, 0, SETVAL, 1);
if (!fork())
{
for (i = 0; i < 10; i++)
{
if (semop(sem, &d, 1) == -1)
error_handler("main | semop [d - father]\n");
if (write(STDOUT_FILENO, "hello\n", 7) == -1)
error_handler("main | write [hello]\n");
if (semop(sem, &u, 1) == -1)
error_handler("main | semop [u - father]\n");
}
} else {
for (i = 0; i < 10; i++)
{
if (semop(sem, &d, 1) == -1)
error_handler("main | semop [d - child]\n");
if (write(STDOUT_FILENO, "world\n", 7) == -1)
error_handler("main | write [world]\n");
if (semop(sem, &u, 1) == -1)
error_handler("main | semop [u - child]\n");
}
// semctl(sem, 0, IPC_RMID);
}
return EXIT_SUCCESS;
}
相反,如果您想同步父子关系中的两个进程(这听起来很奇怪…),我建议您共享内存和POSIX信号量