Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> использование мютексов 
:(
    Опции темы
bagos
Дата 24.11.2010, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 275
Регистрация: 17.6.2006

Репутация: нет
Всего: 1



Всем привет!
Решил разобраться с мютексами, с критик секциями вроде разобрался, если прально понимаю то мютексы тоже самое что и CS, только не для одного процесса а для нескольких.
Нашел задачку и пытаюсь ее реализовать, программировать на с++ только начал, до этого паскаль и дельфи.
Накидал программу, но в процессе отладки вылетают ошибки памяти, посмотрите пожалуйста на код, у меня есть подозрение что ошибка если есть сразу найдется, код небольшой.
Задача:
. Племя из п дикарей ест вместе из большого горшка, который вмешает т кусков тушеного миссионера. Когда дикарь хо¬чет обедать, он ест из горшка один кусок, если только горшок не пуст, иначе дикарь будит повара и ждет, пока тот не наполнит горшок. Повар, сварив обед,  засыпает.  Создать многопоточное  приложение, моделирующее  обед дикарей.

Код

#include "stdafx.h"
#include <iostream>
#include "stdio.h"
#include "windows.h"
#include "process.h"
#include "stdlib.h"
int n = 5; // количество кусков - норма
const int m = 1, // количество производителей 
k = 10;  // количество потребителей
HANDLE hMutex;


DWORD WINAPI Povar(void * arg){    
    int num = 0;
    num = *((int *)arg);
 while(1){
        WaitForSingleObject(hMutex, INFINITE);
        printf(" I'm Povar :)  ");    
        if ( n == 0 )
        {
            printf(" Povar cooking \n");
            n=5;
            printf("povar sdelal %d kuskov meat\n", n );
        }
        printf(" now gorshok have some meat, that i can go to sleep \n" );
        Sleep(1000);
 ReleaseMutex(hMutex);
 Sleep(1000);
 }
return 0;
};
 

DWORD WINAPI Kanibal(void * arg)
{

    int num = 0;
    num = *((int *)arg);
    while(1){
    WaitForSingleObject(hMutex, INFINITE);
 
        printf(" Kanibal  %d very want to eat!!!!! :) \n",num);

        if (n == 0)
        {
            printf(" kanibal ne kushaet, gorshok is empty \n ");
            Sleep(1000);
        }
        else 
        {
            printf(" kanibal nomer %d kushaet  kusok myasa = %d\n", num ,n);
            n--;
            return 0;
 
        }
        ReleaseMutex(hMutex);
     
        Sleep(1000);
        }
        
 return 0;
}; 


int main(int argc, char* argv)
{
    DWORD dwThreadId[k+m];
    HANDLE hThread[k+m];

      hMutex = CreateMutex(NULL, FALSE, _T("MyMutex"));
 

     for (int j=0;j<m;j++)
     {
         hThread[j] = CreateThread(NULL, 0, &Povar, 0, 0, &dwThreadId[j]);
     }


     for (int i=m;i<k+m;i++)
     {
         hThread[i] = CreateThread(NULL, 0, &Kanibal, 0, 0, &dwThreadId[i]);
     }

     WaitForMultipleObjects(11, hThread, TRUE, INFINITE);
    return 0;
}



Это сообщение отредактировал(а) bagos - 24.11.2010, 20:13
PM MAIL   Вверх
WhKitten
Дата 24.11.2010, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 24.11.2010

Репутация: нет
Всего: нет



WinAPI знаю плохо, но возможно цитата из Джеффри Рихтера поможет:
Цитата
Чтобы многопоточные программы, использующие библиотеку С/С++, работали корректно, требуется создать специальную структуру данных и связать ее с каждым потоком, из которого вызываются библиотечные функции. Более того, они должны знать, что, когда Вы к ним обращаетесь, нужно просматривать этот блок данных в вызывающем потоке чтобы не повредить данные в каком-нибудь другом потоке.

Так откуда же система знает, что при создании нового потока надо создать и этот блок данных?. Ответ очень прост - не знает и знать не хочет. Вся ответственность — исключительно на Вас. Если Вы пользуетесь небезопасными в многопоточной среде функциями, то должны создавать потоки библиотечной функцией _beginthreadex, а не Windows-функцией CreateThread.

PM MAIL   Вверх
bagos
Дата 25.11.2010, 00:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 275
Регистрация: 17.6.2006

Репутация: нет
Всего: 1



Потоки отрабатывают и прекращают свою работу, как мне заставить работать их постоянно, чтобы я сам когда надо завершил приложение?
Код

#include "stdafx.h"
#include <iostream>
#include "stdio.h"
#include "windows.h"
#include "process.h"
#include "stdlib.h"
int n = 20; // количество кусков - норма
const int m = 1, // количество производителей 
k = 10;  // количество потребителей
HANDLE hMutex;


DWORD WINAPI Povar(PVOID pvParam)
{    
        WaitForSingleObject(hMutex, INFINITE);
        printf(" I'm Povar :)  ");    
        if ( n == 0 )
        {
            printf(" Povar cooking \n");
            n=20;
            printf("povar sdelal %d kuskov meat\n", n );
        }
        printf(" now gorshok have some meat, that i can go to sleep \n" );
        ReleaseMutex(hMutex);
        Sleep(1000);
 
return 0;
};
 

DWORD WINAPI Kanibal(void * arg)
{
    WaitForSingleObject(hMutex, INFINITE);
        printf(" Kanibal   very want to eat!!!!! :) \n");//,num);
        if (n == 0)
        {
            printf(" kanibal ne kushaet, gorshok is empty \n ");
        }
        else 
        {
            printf(" kanibal nomer  kushaet  kusok myasa = %d\n" ,n);
            n--;
        }
    ReleaseMutex(hMutex);
    Sleep(1000);    
 return 0;
}; 


int main(int argc, char* argv)
{
    DWORD dwThreadId[k+m];
    HANDLE hThread[k+m];
    hMutex = CreateMutex(NULL, FALSE, _T("MyMutex"));
    for (int j=0;j<m;j++)
     {
         hThread[j] = CreateThread(NULL, 0, &Povar, 0, 0, &dwThreadId[j]);
     }


    for (int i=m;i<k+m;i++)
     {
         hThread[i] = CreateThread(NULL, 0, &Kanibal, 0, 0, &dwThreadId[i]);
     }

    WaitForMultipleObjects(k+m, hThread, TRUE, INFINITE);
    return 0;
}



Это сообщение отредактировал(а) bagos - 25.11.2010, 01:18
PM MAIL   Вверх
WhKitten
Дата 25.11.2010, 02:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 24.11.2010

Репутация: нет
Всего: нет



Цитата(bagos @ 25.11.2010,  00:56)
Потоки отрабатывают и прекращают свою работу, как мне заставить работать их постоянно, чтобы я сам когда надо завершил приложение?

Поток может завершится корректно только в том случае, если его функция возвращает управление. Если не нужно завершать поток, функция не должна возвращать управление, т.е должен быть бесконечный цикл или цикл с условием (например: while (threadIsActive[index]), где threadIsActive глобальный массив, установка threadIsActive[index] = 0 завершает поток). Помимо этого поток можно некорректно завершить из него самого с помощью ExitThread и из другого потока с помощью TerminateThread. А ещё он некорректно завершится, как завершится главный поток приложения (если он конечно завершится, а не будет ждать какого-нибудь мьютекса).
И как я уже писал, некорректно использовать CreateThread для создания потока. Надо использовать _beginthreadex http://msdn.microsoft.com/en-us/library/kd...(v=VS.100).aspx

Это сообщение отредактировал(а) WhKitten - 25.11.2010, 02:03
PM MAIL   Вверх
bagos
Дата 25.11.2010, 02:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 275
Регистрация: 17.6.2006

Репутация: нет
Всего: 1



Большое спасибо! Попробую _beginthreadex 
PM MAIL   Вверх
Игорь1024
Дата 25.11.2010, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 11.5.2009
Где: Дальний Восток

Репутация: нет
Всего: нет



Не согласен с WhKitten. В случае если не ипользуешь структуру TIDDATA (по-моему она так называется) можно и CreateThread.
Если ошибаюсь-исправте.
--------------------
The God is real,unless he is declared as integer.
PM MAIL   Вверх
azesmcar
Дата 25.11.2010, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 5
Всего: 211



Цитата

Oops—I Called CreateThread Instead of _beginthreadex by Mistake

You might wonder what happens if you create your new threads by calling CreateThread instead of the C/C++ run-time library's _beginthreadex function. When a thread calls a C/C++ run-time library function that requires the _tiddata structure, here is what happens. (Most C/C++ run-time library functions are thread-safe and do not require this structure.) First, the C/C++ run-time function attempts to get the address of the thread's data block (by calling TlsGetValue). If NULL is returned as the address of the _tiddata block, the calling thread doesn't have a _tiddata block associated with it. At this point, the C/C++ run-time function allocates and initializes a _tiddata block for the calling thread right on the spot. The block is then associated with the thread (via TlsSetValue) and this block stays with the thread for as long as the thread continues to run. The C/C++ run-time function can now use the thread's _tiddata block, and so can any C/C++ runtime functions that are called in the future.

This, of course, is fantastic because your thread runs without a hitch (almost). Well, actually there are a few problems. First, if the thread uses the C/C++ run-time library's signal function, the entire process terminates because the structured exception handling frame has not been prepared. Second, if the thread terminates without calling _endthreadex, the data block cannot be destroyed and a memory leak occurs. (And who would call _endthreadex for a thread created with CreateThread?)


Добавлено через 1 минуту и 44 секунды
Цитата(bagos @  24.11.2010,  20:12 Найти цитируемый пост)
Решил разобраться с мютексами, с критик секциями вроде разобрался, если прально понимаю то мютексы тоже самое что и CS, только не для одного процесса а для нескольких.

неверно. mutex нужен в основном для синхронизации между процессами, для потоков (независимо от количества) сойдет и CS.
http://forum.vingrad.ru/forum/topic-315275.html
PM   Вверх
bsa
Дата 25.11.2010, 13:18 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 1
Всего: 196



Цитата(azesmcar @ 25.11.2010,  11:07)
Цитата(bagos @  24.11.2010,  20:12 Найти цитируемый пост)
Решил разобраться с мютексами, с критик секциями вроде разобрался, если прально понимаю то мютексы тоже самое что и CS, только не для одного процесса а для нескольких.

неверно. mutex нужен в основном для синхронизации между процессами, для потоков (независимо от количества) сойдет и CS.[/URL]

Почему неверно? Имхо, ты сказал тоже самое, только другими словами.  smile 
PM   Вверх
azesmcar
Дата 25.11.2010, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 5
Всего: 211



Цитата(bsa @  25.11.2010,  13:18 Найти цитируемый пост)
Почему неверно? Имхо, ты сказал тоже самое, только другими словами.    

я его слова как-то по другому понял smile 
только дошло о чем речь.
PM   Вверх
xvr
Дата 25.11.2010, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(bagos @  24.11.2010,  20:12 Найти цитируемый пост)
иначе дикарь будит повара и ждет, пока тот не наполнит горшок. 
В текущей реализации часть 'будит повара' отсуствует - дикарь просто сидит и ждет, пока в горшке что то появится.
Тут напрашивается введение дополнительного Event'а - для пробуждения повара (и, опционально, семафора - для учета количества мяса в горшке, что бы дикарь попусту не пробуждался)


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1485 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.