Текущий архив: 2006.02.26;
Скачать: CL | DM;
Вниз
Вторая копия программы ! Найти похожие ветки
← →
Конопелька (2005-12-07 00:12) [0]Здравтвуйте !
Подскажите пожалуйста исключение варианта запуска второй копии программы !! и что б при повторном запуске программы открывалось уже запущеное мое приложение ! у меня есть несколько примеров но они не совсем меня устраивают ! И подскажите обязательно ли для этого нужно знать название программы !и если его изменить получиться ли исключить запуск второй копии !
И тут же еще один вопрос к этой теме ! есть два приложение - первое простое с двумя кнопками (к примеру ) а второе имеет две формы ! и вот нужно что б по нажатию той или иной кнопки открывалось то или иное окно второй программы (уже запущеной) !
Заранее огромное спасибо за помощь ! ))
← →
Eraser © (2005-12-07 00:21) [1]
> Конопелька (07.12.05 00:12)
> Подскажите пожалуйста исключение варианта запуска второй
> копии программы
Создать именованый объект ядра, например мьютекс при старте программы, если объект уже существует, значит копия программы уже запущена.
> у меня есть несколько примеров но они не совсем меня устраивают
чем конкретно?
> обязательно ли для этого нужно знать название программы
не обязательно.
> и вот нужно что б по нажатию той или иной кнопки открывалось
> то или иное окно второй программы (уже запущеной)
легко реализуется через пользовательские сообщения.
см. FindWindow, Send/PostMessage.
← →
Конопелька (2005-12-07 00:26) [2]обьясни пожалуйста как это сделать через Мьютекс !? я с этим не знаком ! и если можна то малеенький наглядный пример !!) ?
← →
Eraser © (2005-12-07 00:35) [3]
> Конопелька (07.12.05 00:26) [2]
В dpr файл проекта вставь перед Application.Initialize
CreateMutex(nil, True, "MyCoolProject");
if GetLastError = ERROR_ALREADY_EXISTS then
begin
MessageBox(0, PChar("Config window already EXISTS!"), SApplicationName, MB_ICONERROR);
Halt;
end;
← →
Alexander Panov © (2005-12-07 01:07) [4]
> легко реализуется через пользовательские сообщения.
Совсем даже не легко.
← →
gdaujk © (2005-12-07 09:12) [5]Eraser © (07.12.05 00:35) [3]
Удобнее для пользователя будет програмное переключение на первый экземпляр:var
UniqueMes: Integer;
const
UNIQUE_APP_STR = "MyCoolProject";
...
UniqueMes := RegisterWindowMessage(UNIQUE_APP_STR);
hMutex := CreateMutex(nil, False, UNIQUE_APP_STR);
if GetLastError = ERROR_ALREADY_EXISTS then
begin
PostMessage(HWND_BROADCAST, UniqueMes, 0, 0);
Exit;
end;
...
и после ловить сообщение с Msg = UniqueMes. При получении показать себя пользователю.
← →
Alexander Panov © (2005-12-07 09:32) [6]
> При получении показать себя пользователю.
Думаю, что как раз этот момент и будет самым сложным;)
← →
Eraser © (2005-12-07 11:31) [7]
> Alexander Panov © (07.12.05 01:07) [4]
Ну эт почему же? :)
2-3 строки + обработка сообщения, imho.
← →
gdaujk © (2005-12-07 11:33) [8]>Alexander Panov © (07.12.05 09:32) [6]
>Думаю, что как раз этот момент и будет самым сложным;)
procedure ForceForegroundWindow(MainWnd: HWND);
var
fPID, cPID: DWORD;
begin
fPID := GetWindowThreadProcessId(GetForegroundWindow, nil);
cPID := GetWindowThreadProcessId(MainWnd, nil);
AttachThreadInput(fPID, cPID, True);
ShowWindow(MainWnd, SW_SHOW);
SetForegroundWindow(MainWnd);
AttachThreadInput(fPID, cPID, False);
end;
PS: сабж был уже много раз. Можно было и поискать...
← →
Alexander Panov © (2005-12-07 12:10) [9]
> gdaujk © (07.12.05 11:33) [8]
Приведенного кода недостаточно для правильного восстановления приложения.
> PS: сабж был уже много раз. Можно было и поискать...
Поэтому высказывание мимо кассы.
← →
Alexander Panov © (2005-12-07 12:17) [10]
> PS: сабж был уже много раз. Можно было и поискать...
Что ж ты сам не поискал правильный ответ?
Например, вот -
http://forum.sources.ru/index.php?showtopic=123826&view=showall
← →
gdaujk © (2005-12-07 13:15) [11]Удалено модератором
← →
Alexander Panov © (2005-12-07 13:46) [12]Удалено модератором
← →
gdaujk © (2005-12-07 14:58) [13]>Alexander Panov © (07.12.05 13:46) [12]
>Прочитай внимательно...
Почитал и понял, что основные ограничения SetForegroundWindow накладываются в Win98/Me, и избавится от оных предлагается SystemParametersInfo. Но я чтитал внимательно и сабж, в котором автором тёмно-серым по светло-серому указаны: NT4, Win2k, WinXP. Вопрос почему-то не "отпадает сам собой". Может я недостаточно внимательно читал???
>В следующий раз выбирай выражения
И какое, по вашему, выражение в контексте фразы: "Желательно аргументировать свою точку зрения, иначе можно прослыть ..." - нужно было употребить?
PS: приведите хоть один пример (ситуацию), в котором при повторном запуске приложения в NT4, Win2k, WinXP вариант [8] "недостаточен для правильного восстановления приложения".
← →
Alexander Panov © (2005-12-07 15:01) [14]gdaujk © (07.12.05 14:58) [13]
PS: приведите хоть один пример (ситуацию), в котором при повторном запуске приложения в NT4, Win2k, WinXP вариант [8] "недостаточен для правильного восстановления приложения".
В MSDN ведь написано ясно:
В случае, если пользователь работает с другим приложением, окно не будет выдвинуто на передний план.
Для этого нужно воспользоватьсяSystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
И т.д.
В W2000 и XP именно так и ведет себя функция SetForegroundWindow и иже с ней - прочто начинает мигать кнопка на панели задач, окно же на передний план не появляется.
← →
Alexander Panov © (2005-12-07 15:02) [15]gdaujk © (07.12.05 14:58) [13]
Почитал и понял, что основные ограничения SetForegroundWindow накладываются в Win98/Me
В W2000 и XP ситуация намного хуже.
← →
gdaujk © (2005-12-07 15:09) [16]Alexander Panov © (07.12.05 15:01) [14]
окно же на передний план не появляется
То есть вы хотите сказать, что при выполнении кода [8] окно на передний план не выходит?
PS: код [8] направлен именно на перенесение окна на передний план, а не на мигание...
← →
gdaujk © (2005-12-07 15:12) [17]>В MSDN ведь написано ясно:
However, on Microsoft Windows 98 and Windows Millennium Edition (Windows Me), if a nonforeground thread calls SetForegroundWindow and passes the handle of a window that was not created by the calling thread, the window is not flashed on the taskbar. To have SetForegroundWindow behave the same as it did on Windows 95 and Microsoft Windows NT 4.0, change the foreground lock timeout value when the application is installed. This can be done from the setup or installation application with the following function call:
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
← →
Alexander Panov © (2005-12-07 15:14) [18]gdaujk © (07.12.05 15:09) [16]
То есть вы хотите сказать, что при выполнении кода [8] окно на передний план не выходит?
Именно.
Вот код:class procedure TDummy.RestoreApp(Sender: TObject);
var
hWnd, hCurWnd, dwThreadID, dwCurThreadID: THandle;
OldTimeOut: Cardinal;
AResult: Boolean;
begin
hWnd := Application.Handle;
SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @OldTimeOut, 0);
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(0), 0);
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
hCurWnd := GetForegroundWindow;
AResult := False;
while not AResult do
begin
dwThreadID := GetCurrentThreadId;
dwCurThreadID := GetWindowThreadProcessId(hCurWnd);
AttachThreadInput(dwThreadID, dwCurThreadID, True);
AResult := SetForegroundWindow(hWnd);
AttachThreadInput(dwThreadID, dwCurThreadID, False);
end;
SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(OldTimeOut), 0);
Application.Restore;
end;
(c) Rouse_ & y-soft
← →
Alexander Panov © (2005-12-07 15:15) [19]gdaujk © (07.12.05 15:12) [17]
В W98 и WindowsNT как раз нет проблем с этим.
В ME не знаю - не использовал.
← →
gdaujk © (2005-12-07 15:24) [20]>Alexander Panov © (07.12.05 15:14) [18]
>Именно.
А у меня, на XP, работает. С чего бы это? Может пришлёте код неработающего приложения?
>Alexander Panov © (07.12.05 15:15) [19]
В W98 ... как раз нет проблем с этим.
А как тогда объяснить gdaujk © (07.12.05 15:12) [17]?
← →
Конопелька (2005-12-07 16:04) [21]Я конечно извиняюсь !! Но я немного непонял наверно ! Вот я сделал так вроде работает ! Но вот в чем проблема ! Один раз он восстанавливает программу ! Но когда второй раз повторно запускаешь программу то он неможет ее закрыть и обработчики событий OnCloseQuery тож неработает и на панели задач она не появляеться !
Вот код программы:program server;
uses
Forms,Windows,ShellAPI,
mainform in "mainform.pas" {mainform1};
{$R *.res}
procedure ForceForegroundWindow(MainWnd: HWND);
var
fPID, cPID: DWORD;
begin
fPID := GetWindowThreadProcessId(GetForegroundWindow, nil);
cPID := GetWindowThreadProcessId(MainWnd, nil);
AttachThreadInput(fPID, cPID, True);
ShowWindow(MainWnd, SW_SHOW);
SetForegroundWindow(MainWnd);
AttachThreadInput(fPID, cPID, False);
end;
var Handle:longint;
begin
Handle:=FindWindow("Tmainform1",nil);
if handle=0 then
begin
Application.Initialize;
Application.CreateForm(Tmainform1, mainform1);
Application.Run;
end
else
begin
ForceForegroundWindow(handle);
end;
end.
Что я сделал неправильно ! ??
← →
Virgo_Style © (2005-12-07 16:08) [22]offtop: ну зачем же столько "!" ?
← →
Alexander Panov © (2005-12-07 16:12) [23]gdaujk © (07.12.05 15:24) [20]
А у меня, на XP, работает. С чего бы это? Может пришлёте код неработающего приложения?
С того, что если работает у тебя в конкретной ситуации, еще не значит, что работать будет везде.
← →
Alexander Panov © (2005-12-07 16:13) [24]gdaujk © (07.12.05 15:24) [20]
Может пришлёте код неработающего приложения?
Откуда я его возьму?
← →
Alexander Panov © (2005-12-07 16:13) [25]gdaujk © (07.12.05 15:24) [20]
Кстати, топик по ссылке прочитал? Там есть замечания и некоторые ссылки на материалы.
← →
gdaujk © (2005-12-07 16:49) [26]Конопелька (07.12.05 16:04) [21]
Ты не правильно делаешь. Правильно попожже напишу. Вообще, роблемма в том, что в VCL приложениях TForm - дочерняя форма. Я же взял код из своей программы, написанной целиком на WinAPI, там всё проще. Сейчас сделаю правильно, выкину сюды...
Alexander Panov © (07.12.05 16:12) [23]
Интересный довод :-). Ващ код в ДОС тоже робить не будет :-))) Приведите конкретный пример...
По топику пробежался глазами... Но SystemParametersInfo - только для Win98/ME.
PS: автор, вы предполагаете работу вашей программы под Win98/ME?
← →
Leonid Troyanovsky © (2005-12-07 17:01) [27]
> gdaujk © (07.12.05 16:49) [26]
> Интересный довод :-). Ващ код в ДОС тоже робить не будет
> :-))) Приведите конкретный пример...
Нет смысла приводить какой-либо пример, бо вместо того, чтобы
неактивный процесс вытаскивал себя в foreground в нарушение
политики MS, можно было законно сделать SetForegroundWindow
из своего foreground приложения.
А всем этим хакерским штучкам судьба жить до очередного SP.
Причем, чем более разрекламированный способ, тем меньше ему жить.
Т.е., если я знаю, как обойти оное ограничение, я ни с кем не поделюсь,
бо (1) нефик идти поперек MS, (2) вдруг мне самому приcпичит поперек.
--
Regards, LVT.
← →
Rouse_ © (2005-12-07 17:53) [28]Хм, код который привел > Alexander Panov © (07.12.05 15:14) [18] вполне документирован в MSDN. Не вижу тут никаких "хакерских штучек" :)
на всякий случай приведу полный вариант примера:
DPR:program Project1;
uses
Windows,
Forms,
Unit1 in "Unit1.pas" {Form1};
{$R *.res}
var
RestoreOldInstance: Cardinal;
begin
CreateMutex(nil, True, "{C68C1DD9-2CB0-4B2F-9A6A-29F4ADE5707D}");
if GetLastError = ERROR_ALREADY_EXISTS then
begin
if MessageBox(0,
"Запуск второй копии приложения запрещен, активизировать предыдущую копию?",
"Ошибка", MB_YESNO + MB_ICONERROR + MB_DEFBUTTON1) = ID_YES then
begin
RestoreOldInstance :=
RegisterWindowMessage("{FC9D27F6-D173-4CF6-8A9A-3A2197C72390}");
PostMessage(HWND_BROADCAST, RestoreOldInstance, 0, 0); // y-soft
end;
Exit;
end;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Форма:unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
RestoreOldInstance: Cardinal;
function ApplicationMessage(var Message: TMessage): Boolean;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function TForm1.ApplicationMessage(var Message: TMessage): Boolean;
var
hWnd, hCurWnd, dwThreadID, dwCurThreadID: THandle;
OldTimeOut: Cardinal;
AResult: Boolean;
begin
Result := False;
if Message.Msg = RestoreOldInstance then
begin
Application.Restore; // y-soft
hWnd := Application.Handle;
SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @OldTimeOut, 0);
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(0), 0);
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
hCurWnd := GetForegroundWindow;
AResult := False;
while not AResult do
begin
dwThreadID := GetCurrentThreadId;
dwCurThreadID := GetWindowThreadProcessId(hCurWnd);
AttachThreadInput(dwThreadID, dwCurThreadID, True);
AResult := SetForegroundWindow(hWnd);
AttachThreadInput(dwThreadID, dwCurThreadID, False);
end;
SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(OldTimeOut), 0);
end;
inherited;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
RestoreOldInstance :=
RegisterWindowMessage("{FC9D27F6-D173-4CF6-8A9A-3A2197C72390}");
Application.HookMainWindow(ApplicationMessage);
end;
end.
← →
gdaujk © (2005-12-07 18:02) [29]Leonid Troyanovsky © (07.12.05 17:01) [27]
А всем этим хакерским штучкам
Почему хакерским? По-моему, вопрос возникает из-за того, что автор, как и многие другие разработчики, считает, что в ситуации, когда пользователь запускает вторую копию, а должна быть только одна, логично было бы показать ему первый экземпляр, ведь пользователь, в общем-то, этого и хочет. А политики MS, как и пути господни, неисповедима :-)))
Обещанный код
Основан на материалах книги: "Delphi 5: руководство разработчика" Стива Тейксейра и Ксавье Пачеко.
Просто присоедините нижеописанный модуль к программе. Больше ничего делать не надо :-)unit gdaMultInst;
interface
implementation
uses Forms, Windows;
var
WProc: TFNWndProc;
hMutex: THandle;
MIError: Integer;
UniqueMes: Integer;
const
MI_ERROR_NONE = 0;
MI_ERROR_FAILSUBCLASS = 1;
MI_ERROR_CREATINGMUTEX = 2;
UNIQUE_APP_STR = "MyCoolProject";
procedure ForceForegroundWindow(MainWnd: HWND);
var
fPID, cPID: DWORD;
begin
fPID := GetWindowThreadProcessId(GetForegroundWindow, nil);
cPID := GetWindowThreadProcessId(MainWnd, nil);
AttachThreadInput(fPID, cPID, True);
ShowWindow(MainWnd, SW_SHOWNORMAL);
SetForegroundWindow(MainWnd);
AttachThreadInput(fPID, cPID, False);
end;
function NewWndProc(Handle: HWND; Msg: Integer; wParam, lParam: Longint): Longint; stdcall;
begin
Result := 0;
if Msg = UniqueMes
then ForceForegroundWindow(Application.Handle)
else
Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
end;
procedure SubClassAplication;
begin
WProc := TFNWndProc(SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(@NewWndProc)));
if WProc = nil
then MIError := MIError or MI_ERROR_FAILSUBCLASS;
end;
procedure DoFirstInstance();
begin
hMutex := CreateMutex(nil, False, UNIQUE_APP_STR);
if hMutex = 0
then MIError := MIError or MI_ERROR_CREATINGMUTEX;
end;
procedure BroadcastFocusMessage();
var
BSMRecipients: DWORD;
begin
Application.ShowMainForm := False;
BSMRecipients := BSM_APPLICATIONS;
BroadcastSystemMessage(BSF_IGNORECURRENTTASK or BSF_POSTMESSAGE,
@BSMRecipients,
UniqueMes,
0, 0);
end;
procedure InitInstance;
begin
SubClassAplication;
hMutex := CreateMutex(nil, False, UNIQUE_APP_STR);
if GetLastError = ERROR_ALREADY_EXISTS then
begin
BroadcastFocusMessage;
Application.Terminate;
end;
end;
initialization
UniqueMes := RegisterWindowMessage(UNIQUE_APP_STR);
InitInstance;
finalization
if WProc <> nil
then SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(WProc));
if hMutex <> 0 then CloseHandle(hMutex);
end.
PS: писал второпях, так что скорее всего есть ошибки...
← →
Leonid Troyanovsky © (2005-12-07 18:07) [30]
> Rouse_ © (07.12.05 17:53) [28]
> Хм, код который привел > Alexander Panov © (07.12.05 15:
> 14) [18] вполне документирован в MSDN. Не вижу тут никаких
> "хакерских штучек" :)
Хакерские штучки - это разнообразные варианты ForceForeground.
Хотя, фокусы SystemParametersInfo ничем не лучше.
Еще раз повторю, вместо того, чтобы законно сделать из своего
foreground приложения SetForegroundWindow, левой ногой тянемся
к правому уху.
И еще рефрен: чего все привязались к мьютексам, семафор -то
гораздо полезней, он хоть 4 байтовое число хранить может.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2005-12-07 18:12) [31]
> gdaujk © (07.12.05 18:02) [29]
Xavi, конечно, уважаемый guy, но этот код очень далек от совершенства.
Особенно мне не нравятся всякие бродкасты.
--
Regards, LVT.
← →
Игорь Шевченко © (2005-12-07 18:27) [32]А вот народу нифига непонятно, почему, собстна нельзя просто вызвать SetForegroundWindow ?
← →
gdaujk © (2005-12-07 18:30) [33]Leonid Troyanovsky © (07.12.05 18:12) [31]
Особенно мне не нравятся всякие бродкасты.
Чем? В Win2k оные никаких проблем не создают...
PS: а что ишшо не нравится? Я поправлю...
← →
Eraser © (2005-12-07 18:33) [34]
> Игорь Шевченко ©
Ну да, по логике, после закрытия текущего окна, активным станет то, для которого вызвана SetForegroundWindow.
← →
Leonid Troyanovsky © (2005-12-07 18:44) [35]
> gdaujk © (07.12.05 18:30) [33]
> PS: а что ишшо не нравится? Я поправлю...
+ Mutex, +ForceForeground и др.
Т.е., берешь именованный FileMapping, и хранишь там нужный хендл окна.
Если маппинг с таким именем уже есть, то читается этот хендл и делается:
h := GetWindowLong(ahwnd, GWL_HWNDPARENT); // окно приложения
if IsIconic(h) then
ShowWindow(h, SW_RESTORE);
SetForegroundWindow(h);
SendMessage(h, WM_COPYDATA, ..);
Halt;
И все, собс-но.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2005-12-07 18:48) [36]
> Eraser © (07.12.05 18:33) [34]
> Ну да, по логике, после закрытия текущего окна,
Это можно сделать до создания окна.
А запущенное юзером, скажем, из экплорера или из комстроки
вторая копия будет foreground (по определению).
--
Regards, LVT.
← →
gdaujk © (2005-12-07 18:52) [37]Leonid Troyanovsky © (07.12.05 18:44) [35]
А говорили: "... ни с кем не поделюсь" :-) Интересный вариант, надо попробовать.
Но в общем-то, на сколько я понял, вам не нравится метод мой, а не его реализация?
PS: А можно ишшо про приемущества семафоров?
← →
Alexander Panov © (2005-12-07 18:57) [38]Игорь Шевченко © (07.12.05 18:27) [32]
почему, собстна нельзя просто вызвать SetForegroundWindow ?
Foreground and Background Windows
Each process can have multiple threads of execution, and each thread can create windows. The thread that created the window with which the user is currently working is called the foreground thread, and the window is called the foreground window. All other threads are background threads, and the windows created by background threads are called background windows.
Each thread has a priority level that determines the amount of CPU time the thread receives. Although an application can set the priority level of its threads, normally the foreground thread has a slightly higher priority level than the background threads. Because it has a higher priority, the foreground thread receives more CPU time than the background threads. The foreground thread has a normal base priority of 9; a background thread has a normal base priority of 7.
The user sets the foreground window by clicking a window, or by using the ALT+TAB or ALT+ESC key combination. To retrieve a handle to the foreground window, use the GetForegroundWindow function. To check if your application window is the foreground window, compare the handle returned by GetForegroundWindow to that of your application window.
An application sets the foreground window by using the SetForegroundWindow function.
Windows NT 4.0 and earlier, Windows 95: If the new foreground window is a top-level window, the system activates it; otherwise, it activates the associated top-level window.
Windows 98/Me/2000/XP: The system restricts which processes can set the foreground window. A process can set the foreground window only if one of the following conditions is true:
The process is the foreground process.
The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The foreground process is being debugged.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
Windows 2000/XP: No menus are active.
Windows 2000/XP: A process that can set the foreground window can enable another process to set the foreground window by calling the AllowSetForegroundWindow function, or by calling the BroadcastSystemMessage function with the BSF_ALLOWSFW flag. The foreground process can disable calls to SetForegroundWindow by calling the LockSetForegroundWindow function.
← →
Alexander Panov © (2005-12-07 19:00) [39]Leonid Troyanovsky © (07.12.05 18:44) [35]
И все, собс-но.
С учетом [38] вообще-то не все;)
← →
gdaujk © (2005-12-07 19:01) [40]Leonid Troyanovsky © (07.12.05 18:48) [36]
Приемущества семафора понял, объяснять не надо.
PS: автор врядли сам справится что с семафорами, что с мутексами, что с маппингами, так что [29] для него сасое то. А я щас семафоры-то наверное попробую...
Страницы: 1 2 вся ветка
Текущий архив: 2006.02.26;
Скачать: CL | DM;
Память: 0.6 MB
Время: 0.081 c