Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> процессы, создание нескольких процессов 
:(
    Опции темы
IgnatM
Дата 1.5.2011, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 8.1.2011

Репутация: нет
Всего: нет



нужно написать программу, которая вычисляет значение интеграла функции 4/(1+Х^2) на интервале значений 0..1, методом трапеций, где каждый элемент суммы, вычисляется в отдельном процессе....

вот мой код, но в чем - то проблема - процессор перегружается и конечное значение интеграла выводиться несколько раз, я так понимаю промежуточные..Помогите пожалйста
Код

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

double func (double x) {
    return 4/(1 + x*x);
}
int
fatal (char *s)
{
  perror (s);
  exit (1);
}

int main (void) {

    int i,N,status,exit_status;
    double a,b,x_f,x_d,h,sum,new_add;
    pid_t pid,p;

    a = 0;
    b = 1;
    N = 20;
    sum = 0.0;
    h = (b - a) / N;
    x_d = a;
    for (i = 0; i < N; i++){
        if ((pid = fork ()) < 0)
             fatal ("Îøèáêà âûçîâà fork ");
        
        if (pid == 0) {
            printf ("Ïîòîìîê %d ïàóçà...\n", getpid ());
            x_f = a + i*h;
            new_add = func(x_d) + func(x_f);
            x_d = x_f;
            //sleep(4);
                                    
        }
        if (waitpid (pid, &status, WNOHANG) == 0)
         {
               perror ("Phter ");
               
         }
        if (WIFEXITED (status)) {
               exit_status = WEXITSTATUS (status);
              printf ("Ñòàòóñ çàâåðøåíèÿ %d ðàâåí %d\n", pid, exit_status);
                                 
        }
        sum = sum + new_add;
        
    }
    sum = h/2 *sum;
    printf ("\nIntegral = %2.2f\n",sum);
    
    return 0;
}




PM MAIL   Вверх
svlary
Дата 3.5.2011, 05:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 8.9.2009

Репутация: 4
Всего: 4



Цитата(IgnatM @  1.5.2011,  16:27 Найти цитируемый пост)
new_add = func(x_d) + func(x_f);

  Т.е. Вы вычисляете значение дельты (new_add) в дочернем процессе, а присуммируете его 
Код

sum = sum + new_add;

  в родительском ? smile
PM MAIL   Вверх
IgnatM
Дата 3.5.2011, 10:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 8.1.2011

Репутация: нет
Всего: нет



Да, так я хотел сделать, но не уверен, что суммирование происходит в родительском.
PM MAIL   Вверх
svlary
Дата 3.5.2011, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 8.9.2009

Репутация: 4
Всего: 4



Цитата(IgnatM @  3.5.2011,  10:18 Найти цитируемый пост)
но не уверен

  Так делать нельзя. Просто потому, что родительский и дочерний процесс работают в разных и никак не связанных областях памяти. Дочерний процесс, в  момент создания. получает КОПИЮ области памяти родительского. Но дальше их дорожки расходятся и пытаться использовать значение переменной дочернего процесса в родительском, то же самое, что использовать подсказки из загробного мира в делах житейских... smile  Короче, искренний совет - читайте доку !
PM MAIL   Вверх
null56
Дата 3.5.2011, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 4
Всего: 12



IgnatM, извиняюсь за любопытство, хоть я и не любопытный, это принципиальная задача делать параллельно эти вычисления?

если приципиально, то через процессы, почитай:
http://linux.die.net/man/2/shmget
http://linux.die.net/man/3/sem_init

через потоки отталкивайся от (pthread)
http://pubs.opengroup.org/onlinepubs/00790.../pthread.h.html

Это сообщение отредактировал(а) null56 - 3.5.2011, 16:36
PM MAIL   Вверх
IgnatM
Дата 3.5.2011, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 8.1.2011

Репутация: нет
Всего: нет



Здесь это не принципиально, нигде использоваться это больше не будет, но все же нужно сделать(( 
PM MAIL   Вверх
null56
Дата 3.5.2011, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 4
Всего: 12



ну если ты принципиально не хочешь использовать потоки, то придется подумать над тем, как передать данные от одного процесса другому... один способ я тебе упомянул выше, но можешь еще воспользоваться неименованными каналами
почитай man pipe
то есть код изменится примерно так
Код

int ipc_pipe[2];
if (pipe(ipc_pipe) == -1) 
{
//... ошибка
}
    for (i = 0; i < N; i++){
        if ((pid = fork ()) < 0)
             fatal ("Îøèáêà âûçîâà fork ");
     
// дочерний процесс   
        if (pid == 0) {
            printf ("Ïîòîìîê %d ïàóçà...\n", getpid ());
            x_f = a + i*h;
            new_add = func(x_d) + func(x_f);
            x_d = x_f;
            //sleep(4);
close(ipc_pipe[0]);
write(icp_pipe[1], &new_add, sizeof(new_add));
close(icp_pipe[1]);
        }

// родительский процесс
close(ipc_pipe[1]);
read(icp_pipe[0], &new_add, sizeof(new_add));
close(icp_pipe[0]);
        if (waitpid (pid, &status, WNOHANG) == 0)
         {
               perror ("Phter ");
               
         }
        if (WIFEXITED (status)) {
               exit_status = WEXITSTATUS (status);
              printf ("Ñòàòóñ çàâåðøåíèÿ %d ðàâåí %d\n", pid, exit_status);
                                 
        }
        sum = sum + new_add;
        
    }

я не проверял, то что набросал, если пахать не будет, почитай man pipe, снизу страницу помощи, есть пример использонвания
http://www.opennet.ru/man.shtml?topic=pipe...2&russian=2

Это сообщение отредактировал(а) null56 - 3.5.2011, 18:39
PM MAIL   Вверх
MAKCim
Дата 3.5.2011, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



еще можно mmap с MAP_SHARED перед форком


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
IgnatM
Дата 8.5.2011, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 8.1.2011

Репутация: нет
Всего: нет



Сделал с помощью pipe. Вот код:
Код

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <assert.h>

double func (double x) {
    return 4/(1 + x*x);
}
int
fatal (char *s)
{
  perror (s);
  exit (1);
}

double add(double x_d,double x_f) {
    return (func(x_d) + func(x_f));
}

int main (void) {
    int i,N,status,exit_status;
    double a,b,x_f,x_d,h,sum,new_add;
    pid_t pid,p;
    int ipc_pipe[2];

    if (pipe(ipc_pipe) == -1) {
         perror("pipe");
         exit(EXIT_FAILURE);
     }
    a = 0; b = 1; sum = 0.0;
    N = 20;
    h = (b - a) / N;
    x_d = a;
    for (i = 0; i < N; i++){
        x_f = x_d + h;
        pid = fork();
        if(pid == 0) {
            new_add = add(x_d,x_f);
            write(ipc_pipe[1], &new_add, sizeof(new_add));
            return ;
        }
        else if (pid == -1){
            printf("Error for");
            
        }
        else{
            wait((int *) 0);        
            read(ipc_pipe[0], &new_add, sizeof(new_add));
            sum = sum + new_add;            
            x_d = x_f;
            //printf("New add = %2.2f\n",new_add);
        }
    }
    close(ipc_pipe[1]);    
    close(ipc_pipe[0]);    
    sum = h/2 *sum;
    printf ("\nIntegral = %2.2f\n",sum);
        
    return 0;
}


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.1286 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.