我正在尝试编写一个程序,其中主进程分配一个共享内存,然后分叉 4 次。然后每个进程递增 1,共享内存中的整数变量 500 次。所以整数变量最终保持了 2500。在访问共享内存之前,进程锁定一个信号量,在写入共享内存之后,进程解锁它。但是程序给了我以下结果。
tracking@ubuntu12.04:~/thread$ ./a.out
shared memory value : 500 by 28488 process
shared memory value : 1000 by 28487 process
shared memory value : 2179 by 28490 process
shared memory value : 1500 by 28489 process
shared memory value : 2500 by 28491 process
tracking@ubuntu12.04:~/thread$ ./a.out
shared memory value : 500 by 28493 process
shared memory value : 1000 by 28492 process
shared memory value : 2500 by 28495 process
shared memory value : 1500 by 28494 process
shared memory value : 2000 by 28496 process
tracking@ubuntu12.04:~/thread$ ./a.out
shared memory value : 500 by 28498 process
shared memory value : 1000 by 28497 process
shared memory value : 1500 by 28501 process
shared memory value : 2000 by 28499 process
shared memory value : 2500 by 28500 process
第一个结果显示奇怪的值,2179。我也认为中间结果应该是有序的,因为一次只有一个进程可以访问共享内存。但是第二个结果显示 500、1000、2500、1500、2000。这是无序的结果。
这是代码片段。
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#define KEY_NUM 9527
#define MEM_SIZE 4096
int main(int argc, char *argv[])
{
    char        buffer[1024];
    char        *c;
    int         i, n, status;
    pid_t       childpid = 0;
    sem_t       my_lock;
    int         counter = 0;
    int         shm_id;
    void        *shm_addr;
    if( (shm_id = shmget(IPC_PRIVATE, MEM_SIZE, IPC_CREAT | 0666)) == -1)
    {
        printf("fail to allocate a shared memory.\n");
        return -1;
    }
    shm_addr = shmat(shm_id, (void*)0, 0);
    *(int*)shm_addr = 0; // initially 0.
    if( sem_init(&my_lock, 1, 1) == -1)
    {
        perror("Could not initialize mylock semaphore");
        exit(1);
    }
    for(i = 0;  i < 4; i++)
        if(0 == fork()) 
            break;      // child process exit for-loop.
    // entry section
    if( sem_wait(&my_lock) == -1)
    {
        perror("Semaphore invalid");
        exit(1);
    }
    // start of critical section.
    for(i = 0 ; i < 500; i++)
    {
        *(int*)shm_addr = *(int*)shm_addr + 1;
    }
    sprintf(buffer, "shared memory value : %d by %ld process\n", *(int*)shm_addr, (long)getpid());
    write(STDOUT_FILENO, buffer, strlen(buffer) );
    // end of critical section.
    // exit section
    if (sem_post(&my_lock) == -1)
    {
        perror("Semaphore done");
        exit(1);
    }
    // remainder section
    if(childpid > 0)
    {
        for(i = 0 ; i < n ; i++) // wait for all children.
            wait(&status);
        shmctl(shm_id, IPC_RMID, 0); // deallocate the shared memory.
    }
    exit(0);
}
我没发现哪里出了问题。我应该怎么办?先感谢您。