#c #multithreading #malloc
#c #многопоточность #malloc
Вопрос:
У меня есть некоторая выделенная память, которую мне нужно разделить между потоками. Я пишу программу на виртуальной машине Linux и использую pthreads. Я не понимаю, как это сделать.
Например, я выделяю память для 5 потоков (по 2 места int для каждого потока):
all_mem = (int*)malloc(5 * 2 * sizeof(int));
и я хочу, чтобы каждый из них записал два значения int в свою собственную часть памяти. Если у меня есть указатель на начало памяти, как я могу получить указатель на какую-либо другую часть памяти?
Комментарии:
1. Будет сложно ответить на этот вопрос без дополнительного контекста. Почему у вас нет возможности каждому потоку выделять свою собственную память? Если они должны выполняться в одном потоке, почему бы не выделить два, по одному для каждого потока? Или, если речь идет не о потоках, а о том, как обращаться к частям памяти, это называется «арифметика указателей», и об этом есть много информации.
2. Предполагая, что
int *all_mem;
,amp;all_mem[2 * i]
указывает на память дляi
-го потока (считая от 0).3. Без подробной информации о том, как вы выполняете потоки, нам трудно вам помочь. Используете ли вы pthreads или openmpi? Предназначена ли эта программа для запуска на аппаратном обеспечении с общей или распределенной памятью?
4. @BobJacobsen, у меня есть задача выделить память в основной программе и разделить уже выделенную память между потоками. По крайней мере, предмет для изучения многопоточности.
5. Взгляните на локальное хранилище потоков (TLS), когда у вас появится такая возможность.
Ответ №1:
Вот простой рабочий пример, который позволяет вам это сделать. Общая идея заключается в том, чтобы создать поток, передать ему индекс (его идентификатор). Затем вы можете использовать этот идентификатор, чтобы ограничить доступ к определенным индексам в вашем массиве.
В приведенном ниже примере a
представляет собой массив, элементы которого суммируются в четырех потоках. Thread0
может получить доступ к a [0: 4], Thread1
может получить доступ к a [4: 8], Thread2
a [8: 12] и, наконец, Thread3
a [12: 16]
#include <stdio.h>
#include <pthread.h>
// size of array
#define MAX 16
// maximum number of threads
#define MAX_THREAD 4
int a[] = { 1, 5, 7, 10, 12, 14, 15, 18, 20, 22, 25, 27, 30, 64, 110, 220 };
int sum[] = { 0 , 0, 0, 0};
void* sum_array(void *arg)
{
int tid = *((int *)arg);
for (int i = MAX_THREAD*tid; i < MAX_THREAD*tid MAX/MAX_THREAD; i ) {
printf("Thread %i is handling %i n", tid, i);
sum[tid] = a[i];
}
}
// Driver Code
int main()
{
pthread_t threads[MAX_THREAD];
// Creating 4 threads
for (int i = 0; i < MAX_THREAD; i ) {
int *arg = malloc(sizeof(int));
*arg = i;
pthread_create(amp;threads[i], NULL, sum_array, (void*)arg);
}
// joining 4 threads i.e. waiting for all 4 threads to complete
for (int i = 0; i < MAX_THREAD; i ) {
pthread_join(threads[i], NULL);
}
// adding sum of all 4 parts
int total_sum = 0;
for (int i = 0; i < MAX_THREAD; i ) {
total_sum = sum[i];
}
printf("sum is %i n", total_sum);
return 0;
}
Комментарии:
1. Я действительно не понимаю, как это работает. Я действительно новичок в потоковой обработке. Я думал, что выделяю память для 5 потоков, создаю их, затем каким-то образом передаю начальный указатель потока и конечный указатель блока памяти и уже в функции потока записываю это. Это неправильный способ?
2. Ответ с минимальным примером. Взгляните
3. спасибо за такой наглядный пример, но здесь память выделяется для каждого потока. Мне нужно, чтобы память выделялась только один раз, но я думаю, что теперь я могу заставить ее работать благодаря вашему ответу.
4. Рад, что это помогает. память в этом случае выделяется только один раз, когда мы объявляем и инициализируем
a
.