Нужна помощь, нужно разработать программу редактирование документа с 2 потоками используя защелку. Пока 1 поток работает, во втором должна быть ошибка. В 2х разных консолях.
Часть кода, не понятно почему не захватывает файл
Недостаточно кода, чтобы понять, в чём проблема. Например, не видно, как создаётся Mymutex. Если он создан неправильно, то, например, возможна ситуация, что каждый поток создаёт собственный мьютекс, так что второй поток успешно лочит свой мьютекс, и ему ничего не мешает зайти в критическую секцию и упасть при попытке открыть файл, который уже открыт на запись первым потоком.
По заданию тоже есть непонимание. Сначала там говориться о двух потоках. Затем есть упоминание о двух разных консолях, что намекает уже о том, что это не два потока, а два процесса. Можно ли прояснить этот пункт?
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
у меня должно быть открыто 2 приложения первое получило доступ к файлу и ждет от меня ввода с клавиатуры чего то там... второе при запуске выдает ошибку из-за того что файл уже захвачен,но на данный момент выходит так что файл не захвачивается и в 2х приложениях ожидание ввода значения
Во-первых что-то не понимаю нафига тут вообще нужна защелка (мьютекс, если выражаться на нормальном программистском языке), если можно просто открыть файл в эксклюзивном режиме? Мьютекс нужен не для того чтобы заблокировать ресурс, то есть в нашем случае файл, для конкурентного процесса, а чтобы синхронизировать работу с конкурентным процессом. Например, если конкурентные процессы будут писать в файл или читать из файла только предварительно захватив мьютекс, то ни один из процессов не сможет увидеть файл в промежуточном (поломанном) состоянии когда кто-то другой начал его изменять и еще не закончил. Мьютекс, кстати, должен быть глобальным и именованным чтобы была только одна копия в рамках всей операционной системы. Иначе у каждого процесса будет свой мьютекс и захват одного мьютекса не будет мешать параллельному захвату другого мьютекса и никакой синхронизации происходить не будет.
Лет 15 уже не тыкал палочкой в MFC, но судя по тому что я вижу у класса CMutex есть параметр в конструкторе - имя мьютекса. если его не указать, а ты его не указываешь, то мьютекс будет локальным. А тебе нужен глобальный.
CMutex Mymutex(FALSE, "my-cool-mutex-42"); //Имя должно быть уникальным чтобы избежать коллизий. Лучше взять GUID: https://www.guidgenerator.com/online-guid-generator.aspx
Ага, собственно именно то, что я и ожидал. При таком объявлении у каждого объекта MyClass будет свой экземпляр мьютекса, и эти экземпляры никак не будет мешать друг другу заходить в критическую секцию кода. Такой подход нужен только в том случае, если методы класса будут вызываться в разных потоках для одного и того же объекта, иными словами, если требуется синхронизировать доступ к this. У нас же по заданию требуется другое - синхронизировать доступ к файлу. В следствие того, что файл один на всех, то и мьютекс, которым будем синхронизировать доступ, тоже должен быть один на всех. То есть, если синхронизировать нужно два потока, то мьютекс нужно делать статическим, а если нужно синхронизировать вообще два экземпляра приложения, то следует делать глобальный именованный мьютекс, как указал Absurd.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
у меня должно быть открыто 2 приложения первое получило доступ к файлу и ждет от меня ввода с клавиатуры чего то там... второе при запуске выдает ошибку из-за того что файл уже захвачен,но на данный момент выходит так что файл не захвачивается и в 2х приложениях ожидание ввода значения
Креэйтфайл без шары.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Возможно функция CreateFile() с определёнными параметрами (или без таковых) позволит как-то улучшить ситуацию, но это всё равно будет не лучшим решением.
Сам факт того, что несколько приложений одновременно должны набрасываться на один файл, говорит о непродуманности системы.
Решается такая задача с помощью клиент-серверной архитектуры.
Т.е. один какой-то один процесс (сервер) имеет монопольный доступ к определённым файлам,
а другие приложения (клиенты) обращаются к нужному файлу опосредованно через этот сервер.
Самое простое решение - использовать готовый FTP-сервер, который можно установить как на локальной машине, так и на удалённой.
Если захочется самому написать некий свой сервер, то для этого Microsoft Visual C++ предлагает как минимум два варианта решения:
- локальный СОМ-сервер (LocalServer)
- Служба Windows (Windows service)
Да здесь ни о какой "правильной" архитектуре и не шла речь никогда. Насколько я понял, это просто упражнение на использование мьютексов. Так что на притянутость за уши самой постановки не стоит обращать внимания
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Возможно функция CreateFile() с определёнными параметрами (или без таковых) позволит как-то улучшить ситуацию, но это всё равно будет не лучшим решением.
Сам факт того, что несколько приложений одновременно должны набрасываться на один файл, говорит о непродуманности системы.
Решается такая задача с помощью клиент-серверной архитектуры.
Помнится давным давно, когда я еще был студентом последнего курса, на SQL.ru водился сочнейший тролль "Люблю ФС" который с невозмутимым видом доказывал тамошним аскакалам что свалка dBASE/Paradox/FoxPro/* файлов на сетвой шаре надежно работает с любым количеством пользоватлей и что это работает быстрее любого SQL. Там все были готовы растерзать мерзкого святотатца, но тот похоже был какой-то редкий спец и знал все тончайшие нюансы про совместный доступ к файлам на нетварной шаре и все аргументы отскакивали от него как горох от бетонной стены.
Возможно этот специалист по SQL был действительно прав.
Ведь служба доступа к файлам и принтерам - это один из сетевых сервисов Windows.
Таким образом мы неявно переводим систему хранения данных на клиент-серверную архитектуру.
Взаимодействие между файловым сервером и клиентом происходит по SMB-протоколу.
С таким же успехом это можно делать и на локальной машине,
т.е. обращаться к собственным файлам не напрямую, а через службу сетевого доступа по протоколу SMB.