繁体   English   中英

与信号量同步

[英]Synchronization with semaphores

该程序在共享内存上运行。 它创建4个子进程,将共享内存中的int值(最初为0)递增到最大MAXCOUNT(此处为100k)。

当孩子看到共享内存中的int值等于MAXCOUNT时,它将停止递增该值。 有时它可以工作,并且共享内存中的int值恰好是MAXCOUNT,有时是上面的1或2。

我的最后一个输出是:

Process 3 incremented value by 24138.
Process 2 incremented value by 26471.
Process 1 incremented value by 23247.
Process 0 incremented value by 26145.
Shared Memory = 100001, MAXCOUNT = 100000

比限制高1。 这怎么可能?如何解决呢?

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <unistd.h>
#include <semaphore.h>

#define MAXCOUNT 100000
#define NUM_CHILDREN 4
#define SHMSEGSIZE sizeof(int)

int main(){
    int i, shmID, *shared_mem, count = 0;
    int pid[NUM_CHILDREN];
    shmID  = shmget(IPC_PRIVATE, SHMSEGSIZE*2, IPC_CREAT | 0644);
    shared_mem  = (int *)shmat(shmID, 0, 0);
    *shared_mem = 0;

    sem_t *mysem = (sem_t*)(shared_mem+1);
    sem_init(mysem, 1, 1);

    for (i=0; i < NUM_CHILDREN; i++) {
        pid[i] = fork();

        if (pid[i] == -1) { return EXIT_FAILURE; }
        if (pid[i] == 0) {

            /* problem here */
            while (*shared_mem < MAXCOUNT) {
                sem_wait(mysem);
                *shared_mem += 1;
                sem_post(mysem);
                count++;
            }   
            /* problem here */

            printf("Process %i incremented value by %i.\n", i, count);
            shmdt(shared_mem);
            return EXIT_SUCCESS;
        }
    }
    for (i=0; i < NUM_CHILDREN; i++) {
        waitpid(pid[i], NULL, 0);
    }
    printf("Shared Memory = %i, MAXCOUNT = %i\n", *shared_mem, MAXCOUNT);
    shmdt(shared_mem);
    shmctl(shmID, IPC_RMID, 0);
    return EXIT_SUCCESS;
}

编辑:

我将问题部分更改为:

while (1) {
    sem_wait(mysem);
    if(*shared_mem < MAXCOUNT){
        *shared_mem += 1;
    }else{
        break;
    }
    sem_post(mysem);
    count++;
}   

但是现在我想我陷入了僵局,因为我的输出是这样的:

Process 2 incremented value by 23775.

在您的代码中,您正在检查*shared_mem < MAXCOUNT 在锁定部分之外

while (*shared_mem < MAXCOUNT) {
    /* XXX: other threads have a chance to change shared_mem before you lock. */
    sem_wait(mysem);
    *shared_mem += 1;
    sem_post(mysem);
    count++;
}

您应该对代码进行重组,以便将检查包括在关键部分中。


编辑

考虑到评论和已编辑的问题:您的新代码在没有解锁信号的情况下中断了。 其他线程仍然卡住。

the posted code has the following loop,
which is checking the value of shared_mem, Then waiting
During that wait, another child process could/will increment shared_mem
Then this child increments shared_mem
the result is over counting

while (*shared_mem < MAXCOUNT)
{
    sem_wait(mysem);
    *shared_mem += 1;
    sem_post(mysem);
    count++;
}

suggest:

do
{
    sem_wait(mysem);
    if( *shared_mem < MAXCOUNT )
    {
        *shared_mem++;
    }
    sem_post(mysem);
    count++;
}  while( *shared_mem <MAX_COUNT );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM