Использование мьютексов для зап Topic is solved

Это русская секция форума wxWidjets. В этой секции вы можете обсуждать любые вопросы, связанные с wxWidgets на вашем родном языке.
Post Reply
SmileGobo
Earned some good credits
Earned some good credits
Posts: 111
Joined: Wed Jul 30, 2008 8:01 am
Location: Russia/MO
Contact:

Использование мьютексов для зап

Post by SmileGobo »

Понадобилось тут лабы выполнить по учебе, наконец то можно блеснуть знаниями о замечательной либе wxWidgets :D. В лабе один из пунктов задания: использования мьютексов для запуска одной копии программы. Полез в доку нашел эти мьютексы, объявил глобально в хидере:

Code: Select all

#ifndef TEST2APP_H
#define TEST2APP_H

#include <wx/app.h>
#include <wx/thread.h>
wxMutex myflag1;
class test2App : public wxApp
{
    public:
        virtual bool OnInit();
};

#endif // TEST2APP_H
Компилирую после чего вылазит месаг:
Image
По нажатию ДА ошибка на стадии линковки:

Code: Select all

-------------- Build: Release in test2 ---------------

Linking executable: bin\Release\test2.exe
obj\Release\test2Main.o:test2Main.cpp:(.bss+0x78): multiple definition of `_myflag1'
obj\Release\test2App.o:test2App.cpp:(.bss+0x4): first defined here
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 0 seconds)
0 errors, 0 warnings
win xp sp2; CodeBlocks/mingw/wxWidgets 2.8.9/wxFormBuilder
web-программирование:PHP,js/Ajax
Kolya
Experienced Solver
Experienced Solver
Posts: 85
Joined: Mon Dec 11, 2006 11:35 am
Location: /dev/null

Re: Использование мьютексов для з

Post by Kolya »

Переменная wxMutex myflag1 обявлена в заголовочном файле и включается в два cpp файла - test2Main.cpp и test2App.cpp. Из-за этого появляются ошибки в линковке.

Что бы этого избежать в заголовочном файле нобходимо написать:

Code: Select all

extern wxMutex myflag1;
И в одном из cpp файлов

Code: Select all

wxMutex myflag1;
Но мютексы лучше не использовать для проверки на запуск одного экземпляра приложения, поскольку другой пользователь может злоумышленно создать мютекс с таким же именем и приложение не запустится ни разу. Лучше в таких случаях создавать файл в temp каталоге пользователя и блокировать его.
SmileGobo
Earned some good credits
Earned some good credits
Posts: 111
Joined: Wed Jul 30, 2008 8:01 am
Location: Russia/MO
Contact:

Post by SmileGobo »

Спасибо, завелось. Но все равно не лочится. Использование мьютексов один из пунктов лаб работы так что ничо не попишешь.

Правильно ли я лочу:

Code: Select all

bool test2App::OnInit()
{
    wxString dmsg=wxString(this->argv[1]);
    test2Dialog* dlg = new test2Dialog(0L, _("wxWidgets Application Template"));
    wxMutexLocker lock(myflag1);
    if (myflag1.TryLock()==wxMUTEX_NO_ERROR ){
        dlg->Alert(dmsg);
    }
    //dlg->Alert()
    dlg->SetIcon(wxICON(aaaa)); // To Set App Icon
    dlg->Show();
    return true;
}
Соответственно при повторном запуске программа не должна выдавать Окошка с месагой(метод Alert);
win xp sp2; CodeBlocks/mingw/wxWidgets 2.8.9/wxFormBuilder
web-программирование:PHP,js/Ajax
Kolya
Experienced Solver
Experienced Solver
Posts: 85
Joined: Mon Dec 11, 2006 11:35 am
Location: /dev/null

Post by Kolya »

Мютекс должен лочится на все время работы приложения, а не только на время инициализации, т.е. wxMutexLocker должен быть в методе OnRun(), а не OnInit().

Вызывать метод TryLock второй раз не надо, поскольку это делает wxMutexLocker

И самая главная проблема в том, что в каждом запущенном приложении должен быть один и тот же мютекс. В данном случае создаются каждый раз при запуске новые мютексы и обойти это можно использованием именованых мютексов. А они есть не на всех платформах, если я правильно понимаю, и соответственно нет в wxWidgets. Но можно выковырять мютекс wxMutexInternal из под wxMSW и использовать его:
http://svn.wxwidgets.org/svn/wx/wxWidge ... thread.cpp
Здесь надо придумать и передать придуманное имя в третий параметр ::CreateMutex
SmileGobo
Earned some good credits
Earned some good credits
Posts: 111
Joined: Wed Jul 30, 2008 8:01 am
Location: Russia/MO
Contact:

Post by SmileGobo »

Ну собственно пока не получалось сделал следующее, учитывая что пишу под винды:

Code: Select all

#include <windows.h>

bool Alone(){
    HANDLE hMutex = CreateMutex(0,TRUE,"UniqueMutex!");
    if(GetLastError() == ERROR_ALREADY_EXISTS){
        CloseHandle(hMutex);
        return false;
    }
    return true;
}

bool test2App::OnInit()
{
    wxString dmsg=wxString(this->argv[1]);
    test2Dialog* dlg = new test2Dialog(0L, _("wxWidgets Application Template"));
    if (!Alone()){
        dlg->Close();
    }
    dlg->SetIcon(wxICON(aaaa)); // To Set App Icon
    dlg->Show();
    return true;
}
Собственно работает и при вызове в OnInit возможно это криво, но мне оказалось более доступно для понимания
win xp sp2; CodeBlocks/mingw/wxWidgets 2.8.9/wxFormBuilder
web-программирование:PHP,js/Ajax
Kolya
Experienced Solver
Experienced Solver
Posts: 85
Joined: Mon Dec 11, 2006 11:35 am
Location: /dev/null

Post by Kolya »

Случайно нашел

Code: Select all

wxSingleInstanceChecker
Который использует мютексы под виндой для проверки на запуск одного экземпляра приложения. Под юниксами он использует правильный путь блокировки файла в домашнем каталоге.

Если там еще покопатся, то можно найти много чего интерестного :).
SmileGobo
Earned some good credits
Earned some good credits
Posts: 111
Joined: Wed Jul 30, 2008 8:01 am
Location: Russia/MO
Contact:

Post by SmileGobo »

Возьму на вооружение! :D
win xp sp2; CodeBlocks/mingw/wxWidgets 2.8.9/wxFormBuilder
web-программирование:PHP,js/Ajax
Post Reply