- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我当前正在尝试在主进程及其子进程之间发送消息。我正在使用消息传递来强制执行关键部分,但子进程中的消息接收功能失败,我不知道是否应该采用不同的方式发送消息。我的消息接收函数正在父进程中获取消息,因此我无法调试用户进程未接收消息的原因。
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);
}
}
用户.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
最佳答案
我在同一个错误中挣扎了一个星期!
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;
希望这会有所帮助!
关于c - msgrcv() 函数在子进程中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40075487/
我使用消息队列将消息从一个进程发送到另一个进程。接收消息的进程仅在完成对 msgrcv 函数的所有调用后才打印输出。我期望的是它会在收到消息时打印数据,但只有在收到所有消息后才会打印数据。 我尝试过更
我有两个程序通过 IPC 队列相互发送和接收消息。然而,有时 msgrcv 函数会得到一条空白消息,而不是接收通过队列实际发送的消息。我已经注释掉了一个我认为应该有效的修复程序,但我想在这里检查一下,
我当前正在尝试在主进程及其子进程之间发送消息。我正在使用消息传递来强制执行关键部分,但子进程中的消息接收功能失败,我不知道是否应该采用不同的方式发送消息。我的消息接收函数正在父进程中获取消息,因此我无
在我的项目中,协议(protocol)(不可更改)指定以下结构: typedef struct { long type; char username[USER_NAME_MAX_LENGTH]; in
this is my code and in the last part,msgrecv does not accept the messages from the queue accourding
所以我的 msgrcv() 函数调用效果很好,但它会在从其他进程接收到的内容中添加字符。 发送方进程发送hello,接收方进程接收hello@\n或hello\n@或hello@ ,因为它随机打印不同
我正在编写一个基本服务器程序,它必须从客户端接收两种类型的消息(第一个消息是类型 1,第二个消息是类型 2)。似乎它没有看到来自已正确发送的客户端的消息(msgsnd 不返回 -1)。我读到这可能是由
我正在开发一个程序,该程序应该像服务器一样运行,不断从消息队列中读取并处理收到的消息。 主循环看起来像这样: while (1) { /* Receive message */ if
我需要一些关于 msgrcv 的帮助...我需要能够接收这样的消息: while(1){ int status = msgrcv(qid, &msg, sizeof(msg.data), us
我构建了一个程序,允许我创建和删除消息队列以及发送和接收消息。 除了接收消息外,一切似乎都正常工作。当我收到结构时,我可以访问类型(我一直用它来表示“收件人”)并打印它,但是存储在结构的 msg 字段
我编写了两个程序,一个使用 msgsnd 发送消息,另一个使用 msgrcv 接收消息。我已经使用这些功能很长一段时间了,但我无法弄清楚接收文件时出现“检测到堆栈粉碎”错误。在该文件中,我尝试将文件的
现在,我正在尝试输出 buf.mtext 的内容,以便在继续我的程序之前确保采用正确的输入。一切似乎都运行良好,除了一件事; msgrcv()将垃圾字符放入缓冲区,接收进程输出垃圾字符。 这是我的发件
我在队列中有许多消息(它们是整数)我想要消费,我想使用整数 int consumed 来跟踪我消费了多少消息。 我首先使用 ds.msg_qnum > 0 检测队列是否有消息,其中 ds 是 stru
我有一个问题。 我有一个进程,假设它是一个客户端,还有一个叫做服务器的进程。客户端和服务器通过同一个队列相互通信。假设客户端向服务器发送一条消息(请求),因此服务器处理它并且应该将消息发送回客户端以确
我有两个不同的程序: 第一个,基本上是无限循环地在消息队列上调用 msgrcv 并在它收到任何东西时打印,在 C++ 中: //foo1.cpp #include #include #includ
我使用 IPC 队列在线程之间进行通信的代码有问题。我需要安全地处理 SIGINT - 当 SIGINT 在关闭之前出现时让程序完成所有事件线程。虽然,我在寻找解决方案时遇到了严重的问题,因为即使使用
#include #include #include #include #include #include #include #include #include struct msg
我正在为考试学习操作系统基础知识,但遇到了一个奇怪的问题。我目前正在研究发送/接收功能。假设我有 3 个主程序 Client,它们通过 msgsnd() 原语发送消息。结构如下: typedef st
我正在unix系统上用C编写代码。我创建了一个消息队列服务器。每次我收到新消息时,我都会 fork ,并且子进程会处理新客户端。服务器等待新的客户端。这是代码。 for (;;) { s
我有一个应用程序,它具有信号处理程序并创建了一个线程来处理消息队列。下面是信号处理程序, /*! \Register handle on SIGINT. */ signal(SIGINT,
我是一名优秀的程序员,十分优秀!