2016-03-07 99 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的增量)。