Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
0 / 0 / 1
Регистрация: 14.02.2011
Сообщений: 153

Не работает процесс/поток

18.04.2013, 18:43. Показов 1428. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Не работает программа, когда пишу вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <sched.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
 
#define NUMSTACK 5000
 
int A[100];
int Pro = 1;
char stack[4][NUMSTACK];
 
int func(void *param)
{
    int i, mult = 1 ;
    int p = *(int *)param; 
    p = p*25 ; 
    for(i = p; i < p+25; i++) 
        mult *= A[i];
    Pro *= mult;
    return 1 ;
}
int main()
{ 
    srand(time(NULL));
    printf("\nМассив: \n");
    for (int i = 0; i < 100; i++)
    {
        A[i] = rand()%2+1;
        printf("%d ", A[i]);
    }
    
    int param[4];
    for (int i = 0; i < 4; i++)
    {
        param[i] = i;
        char  *tostack = stack[i];
        clone(func,(void*)( tostack+ NUMSTACK -1), CLONE_VM, (void *)(param+i));
    }
        
    fprintf (stdout,"\n\nРезультат = %d\n", Pro) ;
    return 1 ;
}
А если записать вот так, то все работает:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>
#include <sched.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
 
#define NUMSTACK 5000
 
int A[100];
int Pro = 1;
char stack[4][NUMSTACK];
 
int func(void *param)
{
    int i, mult = 1 ;
    int p = *(int *)param; 
    p = p*25 ; 
    for(i = p; i < p+25; i++) 
        mult *= A[i];
    Pro *= mult;
    return 1 ;
}
int main()
{ 
    srand(time(NULL));
    printf("\nМассив: \n");
    for (int i = 0; i < 100; i++)
    {
        A[i] = rand()%2+1;
        printf("%d ", A[i]);
    }
    
    int param[4];
    for (int i = 0; i < 3; i++)
    {
        param[i] = i;
        char  *tostack = stack[i];
        clone(func,(void*)( tostack+ NUMSTACK -1), CLONE_VM, (void *)(param+i));
    }
    param[3] = 3 ; 
    char *tostack=stack[3] ;
    clone(func,(void*)( tostack+ NUMSTACK -1), CLONE_VM|CLONE_VFORK, (void *)(param+3)) ;
    
    fprintf (stdout,"\n\nРезультат = %d\n", Pro) ;
    return 1 ;
}
Почему? Разве есть существенная разница?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.04.2013, 18:43
Ответы с готовыми решениями:

Отдельный поток/процесс
Доброго времени суток! Вопрос заключается в следующем: есть COM-порт, с ним ведется работу по прослушиванию: ... настройка...

Как создать поток (процесс) контролирующий работу программы ?
Программа объемная, и соответсвенно :) есть необъяснимые моменты, которые уже тяжело уследить в каком участке кода происходит подвисание....

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

5
1267 / 980 / 385
Регистрация: 02.09.2012
Сообщений: 3,027
20.04.2013, 00:25
Вобще странный способ работы с потоками выбран... почему не POSIX Threads?

Никогда так не использовал, но вероятно вы неверно используете VFORK флаг. См. документацию по clone

CLONE_VFORK
If CLONE_VFORK is set, the execution of the calling process is suspended until the child releases its virtual memory resources
via a call to execve(2) or _exit(2) (as with vfork(2)).

If CLONE_VFORK is not set then both the calling process and the child are schedulable after the call, and an application should
not rely on execution occurring in any particular order.
0
0 / 0 / 1
Регистрация: 14.02.2011
Сообщений: 153
20.04.2013, 19:14  [ТС]
grgdvo, да я не специально. В методичке, с которой я работаю, про POSIX Threads вообще ни слова. И пример работы с потоками, как раз показан только clone. Видимо старая.

grgdvo, можешь еще помочь?
Во общем, я остановился на втором варианте и у меня такая проблема возникла. При произвольном массиве, у меня считается только последний поток. Т.е. если массив из 8 элементов то считается только последние 2 элемента.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <stdio.h>
#include <sched.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
 
#define NUMSTACK 5000
 
int *A;
int n;
int Pro = 1;
char stack[4][NUMSTACK];
 
int func(void *param)
{
    int i, t, mult = 1 ;
    int p = *(int *)param; 
    t = n/4;
    p = p*t; 
    for(i = p; i < p+t; i++) 
        mult *= A[i];
    Pro *= mult;
    return 1 ;
}
int main()
{ 
    printf("\nУкажите размерность массива: ");
    scanf("%d", &n);
    A = (int*)malloc(n*sizeof(int));
    
    srand(time(NULL));
    printf("\nМассив:\n");
    for (int i = 0; i < n; i++)
    {
        A[i] = rand()%3+1;
        printf("%d ", A[i]);
    }
    
    if ((n/4) >= 2)
    {
        int param[4];
        for (int i = 0; i < 3; i++)
        {
            param[i] = i;
            char  *tostack = stack[i];
            clone(func,(void*)( tostack+ NUMSTACK -1), CLONE_VM, (void *)(param+i));
        }
        param[3] = 3 ; 
        char *tostack=stack[3] ;
        clone(func,(void*)( tostack+ NUMSTACK -1), CLONE_VM|CLONE_VFORK, (void *)(param+3)) ;
    }
    
    fprintf (stdout,"\n\nРезультат = %d\n", Pro) ;
    return 1 ;
}
Пока программа не написана до конца. Вообще, я должен написать программу, которая считает произведение элементов произвольного массива с помощью потоков. Каждый поток считает какую ту часть массива.

П.С. мутные темы эти потоки. Не зачти за наглость, а ты не мог бы показать, как выглядела бы программа с POSIX Threads))
0
1267 / 980 / 385
Регистрация: 02.09.2012
Сообщений: 3,027
22.04.2013, 01:00
Вроде работает

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
 
int *A = 0;
int n = 0;
int thread_count = 0;
 
pthread_mutex_t pro_mutex;
int pro = 1;
 
void *func(void *param)
{
    int mult = 1;
    int p = *(int *)param; 
    int t = n / thread_count;
    p = p * t;
    for(int i = p; i < p + t; i++) 
        mult *= A[i];
    pthread_mutex_lock(&pro_mutex);
    pro *= mult;
    pthread_mutex_unlock(&pro_mutex);
 
    return 0;
}
 
int main(int argc, char *argv[]) { 
    printf("Укажите размерность массива: ");
    scanf("%d", &n);
    A = new int[n];
    
    srand(time(NULL));
    printf("Массив:\n");
    for (int i = 0; i < n; i++) {
        A[i] = rand()%3+1;
        printf("%d ", A[i]);
    }
    printf("\n");
    
    printf("Укажите количество потоков: ");
    scanf("%d", &thread_count);
    pthread_t *threads = new pthread_t[thread_count];
    int *thread_data = new int[thread_count];
 
    pthread_mutex_init(&pro_mutex, NULL);
    for (int tindex = 0; tindex < thread_count; tindex++) {
    thread_data[tindex] = tindex;
    pthread_create(&threads[tindex], NULL, func, (void*)&thread_data[tindex]);
    }
 
    for (int tindex = 0; tindex < thread_count; tindex++)
    pthread_join(threads[tindex], NULL);
    pthread_mutex_destroy(&pro_mutex);
 
    delete[] thread_data;
    delete[] threads;
    delete[] A;
 
    printf ("Результат = %d\n", pro);
 
    return 0;
}
Code
1
2
3
4
5
6
7
user@comp ~ $ g++ -o test test.cpp -lpthread
user@comp ~ $ ./test
Укажите размерность массива: 12
Массив:
2 3 1 2 2 3 1 1 3 3 3 2 
Укажите количество потоков: 3
Результат = 3888
1. Если пишем на C++, то уж лучше new/delete вместо malloc. И кстати не забываем delete
2. Принято возвращать 0, когда нет ошибок. Странно, но факт.
3. Для общей переменной (а именно pro) нужна синхронизация. Инча возникает "условие гонок" и какой-то поток запишет свое локальное значение последним.

Не знаю, что еще прокомментировать. Если вопросы, пишите.
1
0 / 0 / 1
Регистрация: 14.02.2011
Сообщений: 153
22.04.2013, 10:46  [ТС]
grgdvo, и снова ОГРОМНОЕ СПАСИБО!

Последний вопрос:
3. Для общей переменной (а именно pro) нужна синхронизация. Инча возникает "условие гонок" и какой-то поток запишет свое локальное значение последним.
Ага, сталкивался таким. Так вот, программа работает, значит ли это, что потоки синхронизированы? Т.е. имеет ли смысл, если я добавлю семафоры для синхронизации потоков?
0
1267 / 980 / 385
Регистрация: 02.09.2012
Сообщений: 3,027
22.04.2013, 14:13
Сами по себе потоки не синхронизированы. Планировщик операционной системы сам думает в каком порядке их исполнять и на каких ядрах (конечно, есть исключения, но это скорее частные случаи, чем общая практика). Такая ситуация с планированием устраивала бы, если бы не необходимость обращения к общим данным. Например, как в вашей задаче, каждый поток должен к общей переменной примножить свое локальное значение. Возникает необходимость упорядочить работу потоков - или синхронизировать. Как это делать? С помощью объектов синхронизации: семафоры (базовый механизм), мьютексы (частный случай семафора, наиболее распространен), критич. секции и многое другое. Применение таких объектов позволяет приостанавливать выполнение одних потоков в пользу других. В частности мьютекс: кто первым заблокировал (lock) мьютекс, тот и будет дальше выполняться. Если другой поток попытается заблокировать уже заблокированный мьютекс, то он (поток) будет приостановлен до момента разблокироваки (unlock) данного мьютекса первым потоком. Это и было реализовано в задаче.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.04.2013, 14:13
Помогаю со студенческими работами здесь

Как запустить процесс и затем ввести данные в поток stdin?
После выполнения команды, далее выводится требование ввести пароль. А как затем ввести этот пароль программно? exec('pg_dumpall', { ...

Определить поток/процесс, которому принадлежит произвольный адрес оперативной памяти
здравствуйте я использую windows 7 помогите определить поток процесс к которому принадлежит произвольный адрес оперативной памяти например...

Windows xp sp3 Процесс Svchost поток Wuaueng.dll грузит систему
Здраствуйте Вопрос по Windows xp sp3 Процесс Svchost Процесс Svchost поток Wuaueng.dll при загрузке через некоторое время начинает...

Процесс работает в консольном приложении, но не работает в форме
Требуется определение типа или пространтсва имен или признак конца файла. namespace ProcessTraining { public partial class Form1...

Не работает поток
Всем доброго времени суток. Ниже представлен код программы, считывающей инф. о пользователе с файла. Проблема: После считывания...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизита табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать контроль заполнения реквизита "ПричинаСписания". . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Программное заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru