2015-10-06 68 views
0

下工作我需要编写被创建子进程的氮量和他们中的每一个单加一到共享存储器变量的程序。我的想法是使用信号量和共享内存,但进程不会彼此等待,并且共享内存变量也不能按我的需要工作。用信号和共享存储器的Linux

mydefs.h

#ifndef __MYDEFS__H__ 
#define __MYDEFS__H__ 
// Includes 
#include <stdio.h> 
#include <unistd.h> 
#include <semaphore.h> 
#include <stdlib.h> 
#include <signal.h> 
#include <errno.h> 
#include <memory.h> 
#include <sys/ipc.h> 
#include <sys/msg.h> 
#include <sys/types.h> 
#include <sys/shm.h> 
#endif // __MYDEFS__H__ 

的main.c

#include "mydefs.h" 
#define PROC_COUNT 3 
#define INITAL_MARKER_VALUE 0 
#define PID_LEN 32 

char mypid[PID_LEN]; 

int main() 
{ 
    int i, shm_id; 
    sem_t mutex; 
    if(sem_init(&mutex,1,1) < 0) 
    { 
     perror("semaphore initilization"); 
     exit(0); 
    } 
    shm_id = shmget(IPC_PRIVATE, 4*sizeof(int), IPC_CREAT | 0666); 
    if (shm_id < 0) { 
     printf("shmget error\n"); 
    } 
    int *shmpointer = shmat(shm_id,0,0); 
    memset(mypid, 0, sizeof(mypid)); 
    sprintf(mypid, "%06d", getpid()); 

    for(i = 0; i < PROC_COUNT; i++) 
    { 
     if (fork() == 0) 
     { 
      while(sem_wait(&mutex)!=0); 
      execl("slaveproc", "slaveproc", mypid, (char *)0); 
      shmpointer += 1; 
      sem_post(&mutex); 
      perror("\n Can't exec slave program. Cause "); 
      exit(1); 
     } 
    } 
    sleep(1); 
    printf("%d\n", *shmpointer); 
    return 0; 
} 

slaveproc.c

#include "mydefs.h" 

int marker; // Marker value 

int main(int argc, char *argv[]) 
{ 
    master_pid = atoi(argv[1]); 
    printf("\n --------------------------------------"); 
    printf("\n I'm the slave proc!"); 
    printf("\n My pid: %d", getpid()); 
    printf("\n My master's pid: %d", master_pid); 
    printf("\n --------------------------------------"); 
    for(;;) pause(); 
     return 0; 
} 
+1

目前尚不清楚你的问题是什么。你是如何得出结论的:“流程不是彼此等待”,以及“不按我想要的工作”的意思是什么?请准确描述预期产出和实际产出。但是对于初学者来说,你在'execl'之后有代码,除非'execl'失败 - execl'不会在成功时返回。所以在成功案例中'shmpointer'不会增加,'sem_post'不会被调用。 – kaylum

+0

此外,在父进程中使用“sleep”并不能保证在运行'printf'时所有子进程都已完成。对于快速测试可能没问题,但需要在生产代码的父级进行适当的同步。 – kaylum

回答

1

的问题(或至少“一个概率lem“)是mutex不在共享内存中:它被分配在堆栈上。当你fork(),新工艺将有来自旧进程完全独立的副本,因此对一个过程调用sem_wait(&mutex)不会影响其他进程的mutex可言。

你应该把mutex共享内存:

int main() 
{ 
    int i, shm_id; 
    shm_id = shmget(IPC_PRIVATE, sizeof(sem_t) + 4*sizeof(int), IPC_CREAT | 0666); 
    if (shm_id < 0) { 
     printf("shmget error\n"); 
    } 
    int *shmpointer = shmat(shm_id,0,0); 
    sem_t *mutex = shmpointer; 
    shmpointer = (void*)shmpointer + sizeof(sem_t); 
    if(sem_init(mutex,1,1) < 0) 
    { 
     perror("semaphore initilization"); 
     exit(0); 
    }   
    memset(mypid, 0, sizeof(mypid)); 
    sprintf(mypid, "%06d", getpid()); 

    for(i = 0; i < PROC_COUNT; i++) 
    { 
     if (fork() == 0) 
     { 
      while(sem_wait(mutex)!=0); 
      execl("slaveproc", "slaveproc", mypid, (char *)0); 
      shmpointer += 1; 
      sem_post(mutex); 
      perror("\n Can't exec slave program. Cause "); 
      exit(1); 
     } 
    } 
    sleep(1); 
    printf("%d\n", *shmpointer); 
    return 0; 
} 

你也从来没有在shmpointer写入内存(也许你的意思(*shmpointer) += 1?),但我要让你明白这一点上你拥有。

+0

经过一些阅读和你的答案我现在明白了。谢谢。 – Lexx