gpt4 book ai didi

c - 如何在 Linux 中使用信号量与 C 同步两个进程的输出?

转载 作者:行者123 更新时间:2023-12-03 12:19:13 25 4
gpt4 key购买 nike

我有以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>

#define SEMAPHORE 0

int main(int argc, char *argv[])
{
int semid, pid, j = 10;
struct sembuf operation;
key_t key;

key = ftok(argv[0], 'U');

if ((semid = semget(key, 1, IPC_CREAT | 0600)) == -1)
{
perror("Error at semget");
exit(-1);
}
semctl(semid, SEMAPHORE, SETVAL, 1);

/* Child is created */
if ((pid = fork()) == -1)
{
perror("Error at fork");
exit(-1);
}
else if (pid == 0)
{
/* Code corresponding to the child process */
while (j)
{
/* DOWN operation is performed at the semaphore */
operation.sem_flg = 0;
operation.sem_op = -1;
operation.sem_num = SEMAPHORE;

semop(semid, &operation, 1);

printf("I AM THE CHILD PROCESS, IMPRESSION: %d\n", j--);

/* UP operation is performed at the semaphore */
operation.sem_op = 1;
operation.sem_num = SEMAPHORE;
semop(semid, &operation, 1);
}
}
else
{
/* Code corresponding to the parent process */
while (j)
{
/* DOWN operation is performed at the semaphore */
operation.sem_flg = 0;
operation.sem_op = -1;
operation.sem_num = SEMAPHORE;

semop(semid, &operation, 1);

printf("I AM THE FATHER PROCESS, IMPRESSION: %d\n", j--);

/* UP operation is performed at the semaphore */
operation.sem_op = 1;
operation.sem_num = SEMAPHORE;
semop(semid, &operation, 1);
}
}
}

所以我可以期待以下输出:

I AM THE FATHER PROCESS, IMPRESSION: 10
I AM THE CHILD PROCESS, IMPRESSION: 10
I AM THE FATHER PROCESS, IMPRESSION: 9
I AM THE CHILD PROCESS, IMPRESSION: 9
I AM THE FATHER PROCESS, IMPRESSION: 8
I AM THE CHILD PROCESS, IMPRESSION: 8
I AM THE FATHER PROCESS, IMPRESSION: 7
I AM THE CHILD PROCESS, IMPRESSION: 7
I AM THE FATHER PROCESS, IMPRESSION: 6
I AM THE CHILD PROCESS, IMPRESSION: 6
I AM THE FATHER PROCESS, IMPRESSION: 5
I AM THE CHILD PROCESS, IMPRESSION: 5
I AM THE FATHER PROCESS, IMPRESSION: 4
I AM THE CHILD PROCESS, IMPRESSION: 4
I AM THE FATHER PROCESS, IMPRESSION: 3
I AM THE CHILD PROCESS, IMPRESSION: 3
I AM THE FATHER PROCESS, IMPRESSION: 2
I AM THE CHILD PROCESS, IMPRESSION: 2
I AM THE FATHER PROCESS, IMPRESSION: 1
I AM THE CHILD PROCESS, IMPRESSION: 1

或者先是 child ,然后是父亲。但是,我运行它,它产生的输出如下:

I AM THE FATHER PROCESS, IMPRESSION: 10
I AM THE FATHER PROCESS, IMPRESSION: 9
I AM THE FATHER PROCESS, IMPRESSION: 8
I AM THE FATHER PROCESS, IMPRESSION: 7
I AM THE FATHER PROCESS, IMPRESSION: 6
I AM THE FATHER PROCESS, IMPRESSION: 5
I AM THE FATHER PROCESS, IMPRESSION: 4
I AM THE FATHER PROCESS, IMPRESSION: 3
I AM THE FATHER PROCESS, IMPRESSION: 2
I AM THE FATHER PROCESS, IMPRESSION: 1
I AM THE CHILD PROCESS, IMPRESSION: 10
I AM THE CHILD PROCESS, IMPRESSION: 9
I AM THE CHILD PROCESS, IMPRESSION: 8
I AM THE CHILD PROCESS, IMPRESSION: 7
I AM THE CHILD PROCESS, IMPRESSION: 6
I AM THE CHILD PROCESS, IMPRESSION: 5
I AM THE CHILD PROCESS, IMPRESSION: 4
I AM THE CHILD PROCESS, IMPRESSION: 3
I AM THE CHILD PROCESS, IMPRESSION: 2
I AM THE CHILD PROCESS, IMPRESSION: 1

或者有时候这个印象出来了,但是我没有得到预期的印象:

I AM THE FATHER PROCESS, IMPRESSION: 10
I AM THE FATHER PROCESS, IMPRESSION: 9
I AM THE CHILD PROCESS, IMPRESSION: 10
I AM THE CHILD PROCESS, IMPRESSION: 9
I AM THE CHILD PROCESS, IMPRESSION: 8
I AM THE CHILD PROCESS, IMPRESSION: 7
I AM THE CHILD PROCESS, IMPRESSION: 6
I AM THE CHILD PROCESS, IMPRESSION: 5
I AM THE FATHER PROCESS, IMPRESSION: 8
I AM THE FATHER PROCESS, IMPRESSION: 7
I AM THE FATHER PROCESS, IMPRESSION: 6
I AM THE CHILD PROCESS, IMPRESSION: 4
I AM THE CHILD PROCESS, IMPRESSION: 3
I AM THE CHILD PROCESS, IMPRESSION: 2
I AM THE CHILD PROCESS, IMPRESSION: 1
I AM THE FATHER PROCESS, IMPRESSION: 5
I AM THE FATHER PROCESS, IMPRESSION: 4
I AM THE FATHER PROCESS, IMPRESSION: 3
I AM THE FATHER PROCESS, IMPRESSION: 2
I AM THE FATHER PROCESS, IMPRESSION: 1

我明白进程的执行顺序直接取决于操作系统,但不是应该当两个进程中的一个执行UP时,另一个应该进入运行吗?

所以我的问题是,这里到底发生了什么?

最佳答案

令 P (sem) 表示信号量 sem 的向下操作,V (sem) 表示信号量 sem 的向上操作。

目前,您的代码是这样的,

// semaphore s1
s1 = 1;
// parent process
P (s1);
// work
V (s1)

// child process
P (s1)
// work
V (s1)

所以这里所说的是,一次只有一个进程可以完成“工作”,而内核会紧随其后。

要同步两个进程的输出,需要做以下事情。

// semaphores, sem-parent, sem-child
sem-parent = 1; sem-child = 0;

// parent process
P (sem-parent);
// work
V (sem-child);

// child process
P (sem-child);
// work
V (sem-parent);

关于c - 如何在 Linux 中使用信号量与 C 同步两个进程的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60896064/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com