2016-10-16 6 views
0

現在、マスタプロセスと子プロセスの間でメッセージを送信しようとしています。私は重要なセクションを強制するためにメッセージの受け渡しを使用していますが、子プロセスのメッセージ受信機能が失敗しています。メッセージを送信する別の方法があるかどうかわかりません。私のメッセージ受信機能が親プロセスでメッセージを受け取っているので、ユーザープロセスが受信していない理由をデバッグするのに問題があります。子プロセスでmsgrcv()関数が失敗しました

oss.c

#include "sharedmem.h" 

pid_t pid; 

//Shared memory and Message queue variables 
key_t key; 
int shm_ID; 

key_t ossMessageKey; 
int ossMessage_ID; 

key_t userMessageKey; 
int userMessage_ID; 

//Clock declaration 
clockStruct *OssClock = NULL; 

//Max number of proccesses to spawn 
const int maxProcesses = 100; 

int process_count = 1; 
char *processNum; 
int totalProcesses = 0; 
int nextUser = 1; 

volatile sig_atomic_t killFlag = 0; 

struct msqid_ds tmpbuf; 

void ReceivedKill(int signum); 
void sendMsg(int msgQueID, int msgType); 
void getMsg(int msgQueID, int msgType, FILE *fp); 

int main(int argc, char *argv[]) 
{ 
    //Processes and general variables 
    int c; 
    int i; 
    int status; 
    int sVal = 5; 
    int tVal = 20; 
    char *logfile = "test.out"; 
    char *user_sVal; 
    char *user_tVal; 
    char *user_shmid; 

    FILE *fp; 

    //Memory allocation 
    user_sVal = malloc(sizeof(int)); 
    user_tVal = malloc(sizeof(int)); 
    user_shmid = malloc(sizeof(int)); 
    processNum = malloc(sizeof(int)); 

    signal(SIGALRM, ReceivedKill); 
    signal(SIGINT, ReceivedKill); 

    //Command line arguments 
    while((c = getopt(argc, argv, "hs:l:t:")) != -1) 
    { 
    switch (c) 
    { 
     case 'h': 
     printf("Options:\n"); 
     printf("[-s]: Change max number of slaves spawned\n"); 
     printf("[-l]: Change name of log file\n"); 
     printf("[-t]: Change number of seconds until Master will terminate itself and all children\n"); 
     exit(0); 
     break; 
     case 's': 
     sVal = atoi(optarg); 
     break; 
     case 'l': 
     logfile = optarg; 
     break; 
     case 't': 
     tVal = atoi(optarg); 
     break; 
     case '?': 
     if(optopt == 's') 
     { 
      exit(1); 
     } 
     else if(optopt == 'l') 
     { 
      exit(1); 
     } 
     else if(optopt == 't') 
     { 
      exit(1); 
     } 
     else 
     { 
      printf("Unknown option entered. Invoke [-h] to see a list of commands\n"); 
      exit(1); 
     } 
    } 
    } 

    sprintf(user_sVal, "%d", sVal); 
    sprintf(user_tVal, "%d", tVal); 


    alarm(tVal); 

    //Setup shared memory 

    //Make our keys 
    if((key = ftok("./", 'x')) == -1) 
    { 
    perror("ftok failed"); 
    exit(1); 
    } 

    if((ossMessageKey = ftok("./", 'y')) == -1) 
    { 
    perror("ftok failed"); 
    exit(1); 
    } 

    if((userMessageKey = ftok("./", 'z')) == -1) 
    { 
    perror("ftok failed"); 
    exit(1); 
    } 

    //Allocate the memory 
    if((shm_ID = shmget(key, sizeof(clockStruct*), IPC_CREAT | 0777)) == -1) 
    { 
    perror("shmget could not allocate"); 
    exit(1); 
    } 

    if((ossMessage_ID = msgget(ossMessageKey, IPC_CREAT | 0777)) == -1) 
    { 
    perror("msgget failed"); 
    exit(1); 
    } 

    if((userMessage_ID = msgget(userMessageKey, IPC_CREAT | 0777)) == -1) 
    { 
    perror("msgget failed"); 
    exit(1); 
    } 



    printf("Attaching memory\n"); 
    //Attach 
    OssClock = (clockStruct *)shmat(shm_ID, 0, 0); 
    OssClock->seconds = 0; 
    OssClock->nanoseconds = 0; 

    printf("Detaching memory\n"); 
    shmdt(OssClock); 

    //printf("Values are: Sval: %d, Logfile: %s, Tval: %d, shm_ID: %d\n", sVal, logfile, tVal, shm_ID); 

    printf("ossMessage_ID: %d, userMessage_ID: %d\n", ossMessage_ID, userMessage_ID); 

    printf("Forking processes\n"); 

    sprintf(user_shmid, "%d", shm_ID); 


    //Process forking 
    for(i = 0; i < sVal; i++) 
    { 

    pid = fork(); 
    //totalProcesses++; 
    process_count++; 

    if(pid == -1) 
    { 
     perror("Failed to fork\n"); 
     exit(1); 
    } 

    if(pid == 0) 
    { 
     sprintf(processNum, "%d", process_count); 
           //arg1  arg2  arg3  arg4  arg5 
     execl("./user", "user", user_sVal, user_tVal, logfile, user_shmid, processNum, (char *) 0); 
     perror("Could not execute user process\n"); 
    } 

    printf("Total Processes: %d\n", process_count); 

    } 

    //Master process 
    if(pid > 0) 
    { 

    sendMsg(userMessage_ID, nextUser); 

    while(totalProcesses < maxProcesses && killFlag != 1) 
    { 
     sleep(5); 
     getMsg(ossMessage_ID, 3, fp); 
     //wait(&status); 
     //process_count--; 
    } 

    printf("Freeing memory\n"); 
    free(user_sVal); 
    free(user_tVal); 
    free(user_shmid); 
    } 

    //Deallocate shared memory 
    printf("Clearing shared memory and message queues\n"); 
    if(shmctl(shm_ID, IPC_RMID, NULL) == -1) 
    { 
    fprintf(stderr, "Shared memory remove failed. Remove manually please\n"); 
    return -1; 
    } 

    if(msgctl(ossMessage_ID, IPC_RMID, NULL) == -1) 
    { 
    perror("msgctl"); 
    exit(1); 
    } 

    if(msgctl(userMessage_ID, IPC_RMID, NULL) == -1) 
    { 
    perror("msgctl"); 
    exit(1); 
    } 

    printf("Program done\n"); 

    return 0; 
} 

void ReceivedKill(int signum) 
{ 
    signal(SIGQUIT, SIG_IGN); 
    signal(SIGALRM, SIG_IGN); 
    signal(SIGINT, SIG_IGN); 

    sleep(1); 
    if(signum == SIGINT) 
    { 
    killFlag = 1; 
    fprintf(stderr, "\n**Received CTRL-C. Killing all children**\n\n"); 
    } 
    else if(signum == SIGALRM) 
    { 
    killFlag = 1; 
    fprintf(stderr, "\n**Timer ran out. Killing all child processes**\n\n"); 
    } 

    kill(-getpgrp(), SIGQUIT); 
    //Sends quit signal to entire slave group which will then use their signal handlers to kill themselves 

} 

void sendMsg(int msgQueID, int msgType) 
{ 
    struct messageBuffer message; 

    printf("Sending message\n"); 

    message.msgtype = msgType; 

    sprintf(message.msgText, "Unblock\n"); 

    if(msgsnd(msgQueID, (void *) &message, sizeof(message.msgText), IPC_NOWAIT) == -1) 
    { 
    perror("Message send error\n"); 
    } 

    printf("Message sent\n"); 

} 

void getMsg(int msgQueID, int msgType, FILE *fp) 
{ 
    msgctl(ossMessage_ID, IPC_STAT, &tmpbuf); 
    struct messageBuffer message; 

    if(msgrcv(msgQueID, (void *) &message, sizeof(message.msgText), msgType, MSG_NOERROR) == -1) 
    { 
    if(errno != ENOMSG) 
    { 
     perror("oss msgrc"); 
    } 
    printf("No message to receive in OSS\n"); 
    } 
    else 
    { 
    printf("Slave %d sent a message back: %s\n", tmpbuf.msg_lspid, message.msgText); 
    totalProcesses++; 

    sendMsg(userMessage_ID, ++nextUser); 
    } 


} 

user.c

#include "sharedmem.h" 


void sigHandler(int signum); 
void sendMsg(int queID, int msgType); 
void getMsg(int queID, int msgType); 
volatile sig_atomic_t killSig = 0; 

clockStruct *OssClock; 

pid_t userPID; 

//Message queue keys and ID's 
key_t ossMessageKey; 
int ossMessage_ID; 

key_t userMessageKey; 
int userMessage_ID; 

int pNum = 0; 

int main(int argc, char *argv[]) 
{ 
    int sVal_num = atoi(argv[1]); 
    int tVal_num = atoi(argv[2]); 
    char *filename = argv[3]; 
    int shm_ID = atoi(argv[4]); 
    pNum = atoi(argv[5]); 
    int keychecker; 
    key_t key; 

    userPID = getpid(); 

    signal(SIGINT, SIG_IGN); 
    signal(SIGQUIT, sigHandler); 

    //printf("Sval: %d, tVal: %d, Filename: %s, shm_ID: %d, Process num: %d\n", sVal_num, tVal_num, filename, shm_ID, pNum); 

    //Shared memory Setup 
    if((key = ftok("./", 'x')) == -1) 
    { 
    perror("ftok for slave failed"); 
    exit(1); 
    } 

    keychecker = shmget(key, sizeof(clockStruct*), IPC_CREAT | 0777); 
    if(keychecker != shm_ID) 
    { 
    perror("Keys do not match. Error passing key to slave?\n"); 
    exit(1); 
    } 

    //Message queues 
    if((ossMessageKey = ftok("./", 'y')) == -1) 
    { 
    perror("ftok for slave failed"); 
    exit(1); 
    } 

    if((userMessageKey = ftok("./", 'z')) == -1) 
    { 
    perror("ftok for slave failed"); 
    exit(1); 
    } 

    if((ossMessage_ID = msgget(ossMessageKey, 0777)) == -1) 
    { 
    perror("msgget"); 
    exit(1); 
    } 

    if((userMessage_ID = msgget(userMessageKey, 0777)) == -1) 
    { 
    perror("msgget"); 
    exit(1); 
    } 

    //printf("ossMessage_ID: %d, userMessage_ID: %d\n", ossMessage_ID, userMessage_ID); 


    //printf("Attaching shared memory\n"); 
    OssClock = (clockStruct*)shmat(shm_ID,0,0); 

    //printf("Seconds: %d, Nanoseconds: %d\n", OssClock->seconds, OssClock->nanoseconds); 


    //Enter critical section 

    getMsg(userMessage_ID, pNum); 
    printf("Slave %d is entering critical section\n", pNum); 

    if(killSig != 1) 
    { 
    //printf("Accessing shared memory\n"); 
    sendMsg(ossMessage_ID, 3); 
    } 




    shmdt(OssClock); 

    kill(userPID, SIGTERM); 
    kill(userPID, SIGKILL); 

    exit(0); 
    return 0; 


} 

void sigHandler(int signum) 
{ 
    killSig = 1; 
} 

void sendMsg(int queID, int msgType) 
{ 
    struct messageBuffer message; 

    message.msgtype = msgType; 

    sprintf(message.msgText, "Slave %d got message\n", pNum); 

    if(msgsnd(queID, (void *) &message, sizeof(message.msgText), IPC_NOWAIT) == -1) 
    { 
    perror("\nuser send error\n"); 
    } 
} 

void getMsg(int queID, int msgType) 
{ 
    struct messageBuffer message; 

    //printf("Got message from oss\n"); 

    if(msgrcv(queID, (void *) &message, sizeof(message.msgText), msgType, MSG_NOERROR | IPC_NOWAIT) == -1) 
    { 
    if(errno != ENOMSG) 
    { 
     perror("user msgrcv"); 
    } 
    printf("User can't receive message\n"); 
    } 
    else 
    { 
    printf("Got message from oss\n"); 
    printf("Message received by user %d: %s\n", pNum, message.msgText); 
    } 
} 

sharedmem.h

#ifndef SHAREDMEM_H 
#define SHAREDMEM_H 

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <unistd.h> 
#include <string.h> 
#include <signal.h> 
#include <getopt.h> 
#include <ctype.h> 
#include <errno.h> 
#include <sys/wait.h> 
#include <sys/shm.h> 
#include <sys/ipc.h> 
#include <sys/types.h> 
#include <sys/msg.h> 

typedef struct clockStruct 
{ 
    int seconds; 
    int nanoseconds; 
} clockStruct; 


//For message queue. Template according to book 
typedef struct messageBuffer 
{ 
    long msgtype; //Type of message 
    char msgText[100]; //Actual message to send. Size is length of message. 
} messageBuffer; 

#endif 

答えて

0
私は同じで苦しんでいた

1週間バグ!

typedef struct messageQueue{ 
    char msgText[MSGTXTLEN]; 
    long int msgType; 
    int pid; 
    int data1; 
    int data2; 
    char opr; 
    int result; 
}msgQdata_s; 

ちょうど構造に

typedef struct messageQueue{ 
    long int msgType; 
    char msgText[MSGTXTLEN]; 
    int pid; 
    int data1; 
    int data2; 
    char opr; 
    int result; 
}msgQdata_s; 

を並べ替えやって固定し、それに

msgQdata_s rc1Data_s; 
rc1Data_s.msgType = 1; 

を送信する前に値を割り当てるしまったが、これが役立つことを願っています!

関連する問題