Разделение выделенной памяти между потоками в C

#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 .