Совместное использование общей переменной двумя функциями в многопоточной среде - PullRequest
0 голосов
/ 21 января 2020

Я пишу многопоточный сценарий использования, где l oop работает непрерывно в функции entry() и заканчивается при вызове exit_loop(). В приведенном ниже примере entry() вызывается с двумя потоками, и выполнение обоих потоков заканчивается, когда вызывается exit_loop().

Теперь я хотел бы немного изменить это, выйдя только из одного потока, когда exit_loop() вызывается первым, то есть entry() вызывается из thread[2], остается, что может быть прекращено при повторном вызове exit_loop(). Чтобы сделать эти два потока независимыми, я мог бы переместить static int loop в локальную область. Но я поражен способом передачи статуса loop между entry() и exit_loop().

Хочу разделить общую переменную между двумя функциями, которая не должна влиять и мешать многопоточному сценарию использования ,

#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<fcntl.h>

static int loop = 1;
void* entry()
{
    int count = 0;
    while(loop)
    {
        count ++;
        printf("\n Count %d, loop %d",count, loop);
    }
}

void exit_loop()
{
    printf("\n Calling exit loop: %d", loop);
    loop = 0;
    printf("\n loop is null %d", loop);
}

void main()
{   
    sem_t* loop1;
    sem_t* loop2;
    pthread_t threadID[5];
    loop1 = sem_open("sem1", O_CREAT | O_EXCL, 0644, 0);
    if (loop1 != SEM_FAILED)
    {   
        printf("\n Created sem 1");
        pthread_create(&threadID[1], NULL, &entry, NULL);// creating thread 1

    printf("Created thread \n ");
}
else
{
    printf("\n Failed to create Semaphore");
}
sem_close(loop1);

loop2 = sem_open("sem2", O_CREAT | O_EXCL, 0644, 0);
if (loop2 != SEM_FAILED)
{   
    printf("\n Created sem 2");
    pthread_create(&threadID[2], NULL, &entry, NULL);//creating thread 2

    printf("Created thread \n ");
}
else
{
    printf("\n Failed to create Semaphore");
}
sem_close(loop2);

printf("Creating exit thread \n");
exit_loop();// exit of both thread

pthread_join(threadID[1],NULL);
pthread_join(threadID[2],NULL);
}

1 Ответ

1 голос
/ 22 января 2020

Если у вас есть два потока, которые необходимо остановить независимо, вам нужны две loop переменные.

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

Объявите свой мьютекс вместе с переменной, которую он защищает:

struct protected_loop_var{
  pthread_mutex_t mutex;
  int value;
};

struct protected_loop_var loop1={PTHREAD_MUTEX_INITIALIZER,1};
struct protected_loop_var loop2={PTHREAD_MUTEX_INITIALIZER,1};

Затем, прежде чем получить доступ к каждой переменной loop, заблокируйте мьютекс и впоследствии разблокируйте мьютекс. Вероятно, проще всего написать отдельные функции для доступа к l oop для инкапсуляции этого.

static int read_loop(struct protected_loop_var* loop){
    pthread_mutex_lock(&loop->mutex);
    int value=loop->value;
    pthread_mutex_unlock(&loop->mutex);
    return value;
}

static void write_loop(struct protected_loop_var* loop,int newval){
    pthread_mutex_lock(&loop->mutex);
    loop->value=newval;
    pthread_mutex_unlock(&loop->mutex);
}

Тогда ваш while в entry может сказать while(read_loop(&loopvar)), а в exit_loop вы можете написать write_loop(&loopvar,0) вместо loop=0, где loopvar равно loop1 или loop2, в зависимости от ситуации.

Если вам нужно запустить один и тот же код в каждом потоке, вы можете передать адрес l oop переменная для этого потока с помощью аргумента void*.

В этом конкретном случае * могут работать другие шаблоны, но мьютекс - это общий инструмент, используемый для защиты многопоточного доступа к общей переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...