Консультация № 181096
04.12.2010, 02:24
66.64 руб.
0 2 1
Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:
вычислить значение функции f(x,k)=(x(2k+1)+x(5k-1))/(2k+1). Вычисление х(2k+1) и x(5k-1) выполнить в двух процессах-потомках соответственно. Задать x и k в родительском процессе и передать сообщением процессам-потомкам. Результаты расчета потомки передают сообщением родителю.

Обсуждение

Неизвестный
04.12.2010, 02:25
общий
Компилятор - gcc.
Неизвестный
04.12.2010, 23:44
общий
это ответ
Здравствуйте, Alexkharkov!
Программа(С++):
Код:
#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
Форма ответа