как заблокировать доступ к бул с мьютексом? - PullRequest
0 голосов
/ 06 июня 2018

решено !: я копирую экземпляр Map в новый поток и не использую ссылку.

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

инициализация потока в Map :: Map ()

pending_orders_mutex = SDL_CreateMutex();
can_process_order = SDL_CreateCond();
chunk_loader_thread = SDL_CreateThread(Map::chunk_loader,"chunk_loader_thread",(void*)this);

loadingнить

int Map::chunk_loader(void * data)
{
    Map map = *(Map*)data;
    bool kill_this_thread = false;

    Chunk_Order actual_order;
    actual_order.load_graphics = false;
    actual_order.x = 0;
    actual_order.y = 0;



    while (!kill_this_thread)
    {
        SDL_LockMutex(map.pending_orders_mutex);            // lock mutex
        printf("3-kill_chunk_loader_thread: %d\n", map.kill_chunk_loader_thread);
        kill_this_thread = map.kill_chunk_loader_thread;
        printf("4-kill_chunk_loader_thread: %d\n", map.kill_chunk_loader_thread);
        if (!kill_this_thread)
        {
            if (map.pending_orders.size())
            {
                actual_order = map.pending_orders.back();
                map.pending_orders.pop_back();
                printf("in thread processing order\n");
            }
            else
            {
                printf("in thread waiting for order\n");
                SDL_CondWait(map.can_process_order, map.pending_orders_mutex);
            }
        }
        SDL_UnlockMutex(map.pending_orders_mutex);          // unlock mutex

        //load actual order
    }
    printf("thread got killed\n");
    return 0;
}

уничтожение нити (основная нить)

SDL_LockMutex(pending_orders_mutex);            // lock mutex
  printf("setting kill command\n");
  printf("1-kill_chunk_loader_thread: %d\n", kill_chunk_loader_thread);
kill_chunk_loader_thread = true;                // send kill command
  printf("2-kill_chunk_loader_thread: %d\n", kill_chunk_loader_thread);
SDL_CondSignal(can_process_order);              // signal that order was pushed
SDL_UnlockMutex(pending_orders_mutex);          // unlock mutex

SDL_WaitThread(chunk_loader_thread, NULL);

консольный вывод

3-kill_chunk_loader_thread: 0
4-kill_chunk_loader_thread: 0
in thread waiting for order
setting kill command
1-kill_chunk_loader_thread: 0
2-kill_chunk_loader_thread: 1
3-kill_chunk_loader_thread: 0
4-kill_chunk_loader_thread: 0
in thread waiting for order

почему mainthread не меняет логическое значение kill_chunk_loader_thread в потоке загрузки?

1 Ответ

0 голосов
/ 06 июня 2018

Прежде всего, вы должны попытаться загрузить минимально полную программу в вопросе.

Похоже, вы установили kill_chunk_loader_thread = true

, но вы не установили map.kill_chunk_loader_thread = true

раздел объявления map неверен из вашего вопроса, но я полагаю, вы не использовали ссылку на локальную или глобальную переменную, или вы просто выполняете копирование структуры, поэтому при изменении одной структуры другаяна это не повлияло.

РЕДАКТИРОВАТЬ:

Map map = *(Map*)data; копирует структуру map (я думаю, конструктор копирования по умолчанию), так что теперь, если исходная карта изменитсякопия не будет.

Вы должны продолжать работать с указателем, например так: Map* pMap = (Map*)data; и проверять указатель следующим образом: kill_this_thread = pMap->kill_chunk_loader_thread;, чтобы вы читали из карты источника.

...