С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

Потоки. Event. Задача про обедающих философов. - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Контрольная http://www.cyberforum.ru/cpp-beginners/thread549459.html
Помогите с контрольной пожалуйста Задание
C++ Итератор для списка #include <iostream> using namespace std; template <class T> class Link { public: T value; Link *nextLink; Link( T v, Link<T>* n ) : value ( v ), nextLink ( n ) {} }; http://www.cyberforum.ru/cpp-beginners/thread549447.html
Запуск программы с удаленного сервера C++
Допустим мы запускаем у себя программу, лежащюю на удаленном сервере(не наша подсеть) и в процессе своей работы программа обращается к IP 10.1.10.1 Вопрос: программа обратится к этому адресу в...
C++ Делаю сапёр. что тут не так????
#include<iostream.h> #include<dos.h> #include<time.h> #include<stdio.h> #include<stdlib.h> #include<conio.h> int main (void) {
C++ Не могу найти ошибку http://www.cyberforum.ru/cpp-beginners/thread549429.html
Добрый день. Есть код #include <stdio.h> #include <conio.h> #include <math.h> struct tbook {
C++ Итерационный метод удаления бинарного дерева Есть бинарное дерево поиска нужно создать итерационный метод удаления дерева. Вот есть функция удаления дерева но при удалении происходит ошибка вот такая: Необработанное исключение в "0x64bd12b4" в... подробнее

Показать сообщение отдельно
VIPerZ
7 / 7 / 0
Регистрация: 26.02.2011
Сообщений: 69

Потоки. Event. Задача про обедающих философов. - C++

16.04.2012, 11:59. Просмотров 5829. Ответов 13
Метки (Все метки)

Здравствуйте, товарищи. Возник вопрос непонимания, по которому не удалось продолбиться с помощью MSDNa и существующих тем на форуме. Что самое интересное - ощущение, что проблема именно с событиями, т.к. очень похожу задачку на потоки, только с семафорами получилось решить без каких-либо проблем. Посему прошу обьяснить в чём я тут не прав...

Задача: за круглым столом сидят философы. Их жизненный цикл состоит из двух состояний: ест и думает. Ест он двумя вилками - правой и левой, а вилки расположены не каждому по две, а между каждыми двумя философами по одной (не зря же они по кругу сидят ). Ну так вот, когда один ест - вилки вокруг него блокируются событиями, а если хотябы одна из вилок занята - он просто забивает на еду и начинает думать.

Мой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// lab1_OS2.cpp: определяет точку входа для консольного приложения.
//обедающие философы
 
#include "stdafx.h"
#include "windows.h"
#include "conio.h"
#include "stdlib.h"
 
#define min_time 300
#define max_time 1700
#define step 4
#define phil_count 10
 
HANDLE some[phil_count]; 
HANDLE Philosopher[phil_count];
 
LPTHREAD_START_ROUTINE WINAPI philosopher(LPVOID arg)
{
    int left_fork = (int)arg, right_fork = left_fork+1;
 
    for(int i = 0; i < step; i++)
    {
        Sleep(min_time + rand()%(max_time-min_time));
        printf("Philosopher[%i] want to eat.\n", left_fork);
        printf("Try to cath forks.\n");
        printf("Left[%i] and right[%i] forks - ", left_fork, right_fork);
        if (WaitForSingleObject(some[left_fork], 1) != WAIT_OBJECT_0 &
            WaitForSingleObject(some[right_fork], 1) != WAIT_OBJECT_0) 
        {
            printf("success.\n");
            SetEvent(some[left_fork]);
            SetEvent(some[right_fork]);
            printf("Eating.");
            Sleep(min_time + rand()%(max_time-min_time));
            ResetEvent(some[left_fork]);
            ResetEvent(some[right_fork]);
        }
        else printf("failed.\n");
 
        Sleep(min_time + rand()%(max_time-min_time));
        printf("Philosopher[%i] THINKING.\n", left_fork);
    }
 
    return 0;
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    for (int i = 0; i < phil_count; i++)
    {
        some[i] = CreateEvent(NULL, TRUE, TRUE, NULL); //FALSE - auto-reset, TRUE - intial state is singaled
        ResetEvent(some[i]);
    }
    for (int i = 0; i < phil_count; i++)
    {
        Philosopher[i] = CreateThread(NULL, 0, philosopher((LPVOID)i), NULL, 0, NULL);
    }
    return 0;
}
С чем в данном коде проблемы: во-первых, как только происходит вызов ф-ции создания потока первый раз - тупо выполняется этот поток, а до его конца мэйн даже не пытается продолжить цикл запуска следующих потоков, а потом, когда первый поток отработал и происходит попытка создания второго потока из мэйна - вылетает эксепшн...

Добавлено через 7 часов 50 минут
Я так заметил, что на эту задачу как-будто принципиально никто не хочет отвечать, а такие темы уже были... неужели так сложно посоветовать что-то? Или хотя бы предложить другой путь реализации, где можно избежать данных проблем?

Добавлено через 38 минут
Я уже понял проблему! Если использовать тип LPTHREAD_START_ROUTINE для функции потока, то этот поток создается в единственном экземпляре и мало того, при попытке создать ещё один поток с типом LPTHREAD_START_ROUTINE вылетает эксепшн, т.к. он должен быть уникальным. Вот.

Но почему я сделал такой тип функции - для других типов программа не компилируется, когда я пытаюсь передать в ф-цию какой-то параметр, пишет, что не может конвертировать в LPTHREAD_START_ROUTINE ... а мне нужно передать параметр - номер философа из цикла...

Добавлено через 46 секунд
Подскажите хотябы, как передать хоть какой-то параметр в поток! А то попытка мудрить с глобальными переменными не привела к успеху
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.