我正在尝试编写一个程序,其中主进程分配一个共享内存,然后分叉 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);
}
我没发现哪里出了问题。我应该怎么办?先感谢您。