2016-03-07 70 views
1

一个内存位置由三个进程共享。每个进程独立地尝试将共享内存位置的内容从1增加到某个值,增量为1。进程1的目标是100000,进程2的目标是200000,目标3是300000.因此,当程序终止时,共享内存变量将总共有600000个(即,这个值将由三个进程中的任何一个最后完成)。我将使用信号量来保护关键部分。 我的问题是,我在初始化信号时遇到了每个进程的SETVAL问题。它使即使我有它设置为1,正确的样本输出和打印“在SETVAL检测到错误”作为我的代码如下所示:三个进程的信号量

Sample output 

From Process 1: counter = 100000. 
From Process 2: counter = 300000. 
From Process 3: counter = 600000. 

Child with ID 2412 has just exited. 
Child with ID 2411 has just exited. 
Child with ID 2413 has just exited. 

       End of Simulation. 



/*ass1*/ 

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

#define SEMKEY ((key_t) 400L) 
// number of semaphores being created 
#define NSEMS 2 

/* change the key number */ 
#define SHMKEY ((key_t) 7890) 


typedef struct 
{ 
    int value; 
} shared_mem; 

shared_mem *total; 

//structure 
int sem_id, sem_id2; 

typedef union{ 
    int val; 
    struct semid_ds *buf; 
    ushort *array; 
} semunion; 

static struct sembuf OP = {0,-1,0}; 
static struct sembuf OV = {0,1,0}; 
struct sembuf *P =&OP; 
struct sembuf *V =&OV; 
//function 
int Pop() 
{ 
    int status; 
    status = semop(sem_id, P,1); 
    return status; 
} 
int Vop() 
{ 
    int status; 
    status = semop(sem_id, V,1); 
    return status; 
} 




/*----------------------------------------------------------------------* 
* This function increases the value of shared variable "total" 
* by one with target of 100000 
*----------------------------------------------------------------------*/ 

void process1() 
{ 
    int k = 0; 

    while (k < 100000) 
    { 


     Pop(); 
     if (total->value < 600000) { 
     total->value = total->value + 1; 
     } 

     Vop(); 
     k++; 

    } 


    printf ("From process1 total = %d\n", total->value); 

} 


/*----------------------------------------------------------------------* 
* This function increases the vlaue of shared memory variable "total" 
* by one with a target 200000 
*----------------------------------------------------------------------*/ 

void process2() 
{ 
    int k = 0; 

    while (k < 200000) 
    { 


     Pop(); 
     if (total->value < 600000) { 
     total->value = total->value + 1; 
     } 

     Vop(); 
     k++; 
    } 

    printf ("From process2 total = %d\n", total->value); 

} 

/*----------------------------------------------------------------------* 
* This function increases the vlaue of shared memory variable "total" 
* by one with a target 300000 
*----------------------------------------------------------------------*/ 
void process3() 
{ 
    int k = 0; 

    while (k < 300000) 
    { 


    Pop(); 
    if (total->value < 600000) { 
     total->value = total->value + 1; 
    } 

    Vop(); 
    k++; 
    } 

    printf ("From process3 total = %d\n", total->value); 

} 


/*----------------------------------------------------------------------* 
* MAIN() 
*----------------------------------------------------------------------*/ 

int main() 
{ 
    int shmid; 
    int pid1; 
    int pid2; 
    int pid3; 
    int ID; 
    int status; 


    char *shmadd; 
    shmadd = (char *) 0; 

    //semaphores 
    int semnum = 0; 
    int value, value1; 
    semunion semctl_arg; 
    semctl_arg.val =1; 

    /* Create semaphores */ 
    sem_id = semget(SEMKEY, NSEMS, IPC_CREAT | 0666); 
    if(sem_id < 0) 
    printf("creating semaphore"); 

    sem_id2 = semget(SEMKEY, NSEMS, IPC_CREAT | 0666); 
    if(sem_id2 < 0) 
    printf("creating semaphore"); 

    /* Initialize semaphore */ 
    value1 =semctl(sem_id, semnum, SETVAL, semctl_arg); 

    value =semctl(sem_id, semnum, GETVAL, semctl_arg); 
    if (value < 1) 
    printf("Eror detected in SETVAL"); 




/* Create and connect to a shared memory segmentt*/ 

    if ((shmid = shmget (SHMKEY, sizeof(int), IPC_CREAT | 0666)) < 0) 
    { 
     perror ("shmget"); 
     exit (1); 
    } 


if ((total = (shared_mem *) shmat (shmid, shmadd, 0)) == (shared_mem *) -1) 
    { 
     perror ("shmat"); 
     exit (0); 
    } 


    total->value = 0; 

    if ((pid1 = fork()) == 0) 
    process1(); 

    if ((pid1 != 0) && (pid2 = fork()) == 0) 
    process2(); 

    if ((pid1 != 0) && (pid2 != 0) && (pid3 = fork()) == 0) 
    process3(); 


    waitpid(pid1, NULL, 0); 
    waitpid(pid2, NULL, 0); 
    waitpid(pid3, NULL, 0); 

    if ((pid1 != 0) && (pid2 != 0) && (pid3 != 0)) 
    { 
     waitpid(pid1); 
     printf("Child with ID %d has just exited.\n", pid1); 

     waitpid(pid2);  
     printf("Child with ID %d has just exited.\n", pid2); 

     waitpid(pid3); 
     printf("Child with ID %d has just exited.\n", pid3); 

     if ((shmctl (shmid, IPC_RMID, (struct shmid_ds *) 0)) == -1) 
    { 
     perror ("shmctl"); 
     exit (-1); 
    } 

     printf ("\t\t End of Program\n"); 

     /* De-allocate semaphore */ 
     semctl_arg.val = 0; 
     status =semctl(sem_id, 0, IPC_RMID, semctl_arg); 
     if(status < 0) 
     printf("Error in removing the semaphore.\n"); 
    } 

} 
+0

对不起,编辑。 – Antoninus

+0

我试了一下代码,它对我很有用。我建议你检查第一个'semctl'的返回值。对于'semctl',如果返回值为'-1',则应该使用'perror'来检查'errno'。 – dancancode

+0

它很奇怪,我再次运行代码,它的工作原理,但当我再次做了它,我又开始再次获得相同的错误。在这些情况下,回报确实是-1。 – Antoninus

回答

2

一些基础知识 - 公益最后长于过程,从而得到了上述使用ipcsipcrm删除运行之间的预先存在的ipcs。确保您在执行后删除了ipcs

waitpid(pid1, NULL, 0); 
waitpid(pid2, NULL, 0); 
waitpid(pid3, NULL, 0); 

本节将为儿童运行 - 他们可能不应该这样做。

total->value = total->value + 1; 

IPC不安全,可能会出现不同的结果(proc1可能会覆盖proc2的增量)。