#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <limits>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
using namespace std;
// Это будет использоваться для генерации ключа
const int ID = 1;
// Данные, которые будем передавать
struct data_t
{
double x;
unsigned k;
};
// Сообщение
struct message
{
long msgtype;
// Объединил только из лени. Неохота писать еще одну struct
union
{
data_t srcdata;
double result;
} data;
};
// Будем использовать для ввода данных
template<class T> T input(const char* const msg);
// Процессы
int process1();
int process2();
// Будем использовать для запуска процессов.
pid_t startProcess(int (*proc)());
/*
*
*/
int main(int argc, char** argv)
{
// Получим ключ
key_t key = ftok(".", ID);
// Создадим очередь
int msqid = msgget(key, IPC_CREAT);
if (msqid == -1)
{
perror("msgget");
exit(EXIT_FAILURE);
}
// Запустим потомки
pid_t children[2] = {startProcess(process1), startProcess(process2)};
// Ввод
double x = input<double>("X:");
unsigned k = input<unsigned>("K:");
// Готовим сообщения
message msg1, msg2;
msg1.data.srcdata.x = msg2.data.srcdata.x = x;
msg1.data.srcdata.k = msg2.data.srcdata.k = k;
msg1.msgtype = 1;
msg2.msgtype = 2;
// Отсылаем
if ((msgsnd(msqid, &msg1, sizeof (msg1.data), 0) == -1) || (msgsnd(msqid, &msg2, sizeof (msg2.data), 0) == -1))
{
perror("msgsnd");
exit(EXIT_FAILURE);
}
message res1, res2;
// Получаем ответ
if (msgrcv(msqid, &res1, sizeof (res1.data), 3, 0) == -1 || msgrcv(msqid, &res2, sizeof (res2.data), 3, 0) == -1)
{
perror("msgrcv");
exit(EXIT_FAILURE);
}
// Считаем результат
double result = (res1.data.result + res2.data.result) / (2 * k + 1);
cout << "Результат:" << result << endl;
return (EXIT_SUCCESS);
}
template<class T>
T input(const char* const msg)
{
T res = 0;
while (true)
{
cout << msg;
cin >> res;
if (cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Ошибка ввода." << endl;
}
else
{
return res;
}
}
}
int process1()
{
// Получаем ключ аналогичным образом
key_t key = ftok(".", ID);
// Очередь
int msqid = msgget(key, 0);
if (msqid == -1)
{
perror("msgget");
return EXIT_FAILURE;
}
message inmsg, outmsg;
// Получаем сообщения
if (msgrcv(msqid, &inmsg, sizeof (inmsg.data), 1, 0) == -1)
{
perror("msgrcv");
return EXIT_FAILURE;
}
// Готовим ответ
outmsg.msgtype = 3;
outmsg.data.result = inmsg.data.srcdata.x * (2 * inmsg.data.srcdata.k + 1);
// Отсылаем
if (msgsnd(msqid, &outmsg, sizeof (outmsg.data), 0) == -1)
{
perror("msgsnd");
return EXIT_FAILURE;
}
return 0;
}
int process2()
{
key_t key = ftok(".", ID);
int msqid = msgget(key, 0);
if (msqid == -1)
{
perror("msgget");
return EXIT_FAILURE;
}
message inmsg, outmsg;
if (msgrcv(msqid, &inmsg, sizeof (inmsg.data), 2, 0) == -1)
{
perror("msgrcv");
return EXIT_FAILURE;
}
outmsg.msgtype = 3;
outmsg.data.result = inmsg.data.srcdata.x * (5 * inmsg.data.srcdata.k - 1);
if (msgsnd(msqid, &outmsg, sizeof (outmsg.data), 0) == -1)
{
perror("msgsnd");
return EXIT_FAILURE;
}
return 0;
}
pid_t startProcess(int (*proc)())
{
pid_t result = 0;
// Создаем процесс
if ((result = fork()) == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
else if (!result)
{
// В потомке запускаем функцию
_exit(proc());
}
// Вернем pid хотя в данной программе и не используем
return result;
}
X:4
K:2
Результат:11.2
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.