C 中的信号量示例
Semaphore example in C
我正在尝试在 C
中制作一个简单的信号量示例,其中有两个 while 循环,将在没有线程的情况下使用两个不同的进程产生此结果:
abcd
abcd
abcd
abcd
因为我不能使用 pthreads,所以我尝试使用通用的 signal()
和 wait()
方法,但由于某些原因,我在 [=] 中的 wakeup
调用中出错17=]方法。
#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
wait(sem_t *s)
{
s=s-1;
if (s<0)
block(); // add process to queue
}
signal(sem_t *s)
{
s=s+1;
if (s<=0)
wakeup(p); // remove process p from queue
}
init(sem_t *s , int v)
{
s=v;
}
void main(void)
{
int i;
// place semaphore in shared memory
sem_t *child_sem = mmap(NULL,sizeof(*child_sem),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
sem_t *parent_sem = mmap(NULL,sizeof(*parent_sem),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
init(child_sem, 1); // create child semaphore
init(parent_sem, 1); // create parent semaphore
if (fork())
{
for (i = 0; i < 10; i++)
{
if (wait(child_sem) < 0)
perror("sem_wait");
printf("ab");
if (signal(parent_sem) < 0)
perror("sem_post");
sleep(1); // required to maintain thread order
}
}
else
{
for (i = 0; i < 10; i++)
{ // parent starts waiting
if (wait(parent_sem) < 0)
perror("sem_wait");
printf("cd\n");
if (signal(child_sem) < 0)
perror("sem_post");
}
}
}
输出:
[Error] In function 'signal':
[Error] 'p' undeclared (first use in this function)
问题是我怎么能在唤醒调用中输入进程 p?
我应该在方法中使用 pid=fork()
吗?
我是否应该在 signal
方法中使用额外的参数,但它会是什么样子? pid p
?
如果我从 wakeup
中删除 p 参数,那么像 PROT_READ
这样的变量会因为某些原因变得未声明。
P.S。代码来自本站。
我不会写完整的东西,但这是解决这个问题的更好方法。
- 使用 2 个信号量。
- 运行信号量1为高时的第一个进程
- 运行信号量2为高时的第二个进程
- 在第一个进程的临界区开始时,使第二个信号量为低,这样资源就不能被第二个进程使用
- 在第一个进程的临界区结束时,使第二个信号量= 1和第一个信号量= 0
- 第二个过程完全相反,即声明sem1 = 0,结束sem1 = 1,sem2 = 0。
这可能会解决问题。永远不要使用 signal
,而是使用 sigaction
。
我正在尝试在 C
中制作一个简单的信号量示例,其中有两个 while 循环,将在没有线程的情况下使用两个不同的进程产生此结果:
abcd
abcd
abcd
abcd
因为我不能使用 pthreads,所以我尝试使用通用的 signal()
和 wait()
方法,但由于某些原因,我在 [=] 中的 wakeup
调用中出错17=]方法。
#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
wait(sem_t *s)
{
s=s-1;
if (s<0)
block(); // add process to queue
}
signal(sem_t *s)
{
s=s+1;
if (s<=0)
wakeup(p); // remove process p from queue
}
init(sem_t *s , int v)
{
s=v;
}
void main(void)
{
int i;
// place semaphore in shared memory
sem_t *child_sem = mmap(NULL,sizeof(*child_sem),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
sem_t *parent_sem = mmap(NULL,sizeof(*parent_sem),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
init(child_sem, 1); // create child semaphore
init(parent_sem, 1); // create parent semaphore
if (fork())
{
for (i = 0; i < 10; i++)
{
if (wait(child_sem) < 0)
perror("sem_wait");
printf("ab");
if (signal(parent_sem) < 0)
perror("sem_post");
sleep(1); // required to maintain thread order
}
}
else
{
for (i = 0; i < 10; i++)
{ // parent starts waiting
if (wait(parent_sem) < 0)
perror("sem_wait");
printf("cd\n");
if (signal(child_sem) < 0)
perror("sem_post");
}
}
}
输出:
[Error] In function 'signal':
[Error] 'p' undeclared (first use in this function)
问题是我怎么能在唤醒调用中输入进程 p?
我应该在方法中使用 pid=fork()
吗?
我是否应该在 signal
方法中使用额外的参数,但它会是什么样子? pid p
?
如果我从 wakeup
中删除 p 参数,那么像 PROT_READ
这样的变量会因为某些原因变得未声明。
P.S。代码来自本站。
我不会写完整的东西,但这是解决这个问题的更好方法。
- 使用 2 个信号量。
- 运行信号量1为高时的第一个进程
- 运行信号量2为高时的第二个进程
- 在第一个进程的临界区开始时,使第二个信号量为低,这样资源就不能被第二个进程使用
- 在第一个进程的临界区结束时,使第二个信号量= 1和第一个信号量= 0
- 第二个过程完全相反,即声明sem1 = 0,结束sem1 = 1,sem2 = 0。
这可能会解决问题。永远不要使用 signal
,而是使用 sigaction
。