Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / проверка на запуск потока / 22 сообщений из 22, страница 1 из 1
21.10.2012, 11:26
    #38007094
spyker
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
Всем привет, вопрос такой, у меня есть поток
допустим когда я его запускаю он работал, а вот когда второй раз я его запускаю
он мне выдавал сообщений что поток уже работает, и не запускал программу!

вот попробовал сделать так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
HANDLE hMutex = OpenMutex( MUTEX_ALL_ACCESS, 0, L"grafic1" );
 
        if (!hMutex)
            hMutex = CreateMutex( 0, 0, L"grafic1" );
        else
        {
            AfxMessageBox(L"Программа уже Активирована",IDCANCEL,0 );
          TerminateThread(hThread,id);
            // return 0;
        }



этот код я поставил в кнопку запуска потока
но все равно как-то не ахти, подскажите пожалуйста как сделать?
...
Рейтинг: 0 / 0
21.10.2012, 11:41
    #38007105
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
spykerвсе равно как-то не ахти
Не просто "не ахти", а "совершенно неработоспособно".

Никаких "OpenMutex" - сразу делай "CreateMutex" и обрабатывай ошибку ERROR_ALREADY_EXISTS.
И разберись, что тебе нужно "не запускал программу" или "поток". Поскольку предотвращать
запуск программы в потоке несколько... странно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
21.10.2012, 11:44
    #38007107
spyker
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
Dimitry Sibiryakov,

я имею в виду то, чтоб 1 раз программу запустил - она работает, а потом хочешь еще раз экземпляр из папки дебага запустить, выдавалось сообщение о точ что программа уже запущена!
...
Рейтинг: 0 / 0
21.10.2012, 11:50
    #38007113
spyker
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
т.е. вот так

Код: plaintext
1.
2.
3.
4.
5.
HANDLE hMutex= CreateMutex( NULL, TRUE, "MyProgram" );
  if(GetLastError() == ERROR_ALREADY_EXISTS)
            {
                 а вот тут что писать?
            }
...
Рейтинг: 0 / 0
21.10.2012, 12:05
    #38007124
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
Нихрена не понял. Тебе нужно, чтобы поток НЕ запускался дважды или наоборот запускался?

Если надо контролировать повторный запуск, то достаточно взять описатель ранее созданного(ых) потока(ов) и проверить работает ли он.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
HANDLE hThread1 = (HANDLE) ::_beginthreadex(...);
if (hThread1)			// поток создан успешно
{
	DWORD dwExitCode;
	if (::GetExitCodeThread(hThread1, &dwExitCode) && dwExitCode == STILL_ACTIVE)
		// поток hThread1 жив!
}


Если связываться с описателями не хочешь, то можно использовать какой-нибудь счетчик кол-ва запусков. Каждый раз, когда запускается новый поток счетчик увеличивается на 1. Когда поток завершает свою работу счетчик уменьшается на 1. Если счетчик = 0, то ни одного экземпляра потока не выполняется. Естественно придется предусмотреть механизм индивидуального доступа к счетчику, а так же вариант того, что поток может грохнутся и счетчик не будет уменьшен на 1.
Одним словом, тут вариантов реализации до фига и больше.

Если же ты хочешь чтобы поток запускался несколько раз, то здесь никаких проблем быть не должно, ведь потоки для этого и существуют, чтобы их запускали много раз, при условии, что ты сам не заблокировал доступ к этой возможности.
...
Рейтинг: 0 / 0
21.10.2012, 12:17
    #38007132
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
spykerDimitry Sibiryakov,

я имею в виду то, чтоб 1 раз программу запустил - она работает, а потом хочешь еще раз экземпляр из папки дебага запустить, выдавалось сообщение о точ что программа уже запущена!
Аааа, понял.

Кто ж контролирует запуск процессов по потокам ? Улавливаешь разницу?

Код: plaintext
1.
2.
3.
4.
5.
HANDLE hMutex= CreateMutex( NULL, TRUE, "MyProgram" );
  if(GetLastError() == ERROR_ALREADY_EXISTS)
            {
                 а вот тут что писать?
            }


Писать нужно то, что требуется, чтобы корректно завершить ненужный процесс, например,

Код: plaintext
1.
2.
3.
4.
5.
HANDLE hMutex = ::CreateMutex(NULL, FALSE, mutex_unique_name);
if (hMutex && ::GetLastError() == ERROR_SUCCESS)
	g_hInstancesMutex = hMutex;		// мьютекс создан успешно, сохраним результат
else
	return ERROR_SINGLE_INSTANCE_APP;	// единственный экземпляр уже выполняется


Кстати этот вариант не будет полным спасением от повторного запуска, у Рихтера есть пример с разделяемой секцией в exe файле, я бы подстраховался и прикрутил бы и ее до кучи
...
Рейтинг: 0 / 0
21.10.2012, 12:29
    #38007140
spyker
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
Cerebrum,

а этот код нужно в потоке писать лучше?
...
Рейтинг: 0 / 0
21.10.2012, 12:51
    #38007158
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
spykerCerebrum,

а этот код нужно в потоке писать лучше?
Какой код? Проверяющий существование мьютекса?
Если да, то естественно в потоке, в первичном, в котором у тебя ф-ция main

Вообще-то любой код всегда выполняется в потоке, процесс на пользовательском уровне - это абстракция.
...
Рейтинг: 0 / 0
21.10.2012, 13:06
    #38007175
spyker
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
Cerebrum,

если в первичном то кнопка старта типа void и она мне ретурн не вернет
...
Рейтинг: 0 / 0
21.10.2012, 13:21
    #38007187
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
spykerCerebrum,

если в первичном то кнопка старта типа void и она мне ретурн не вернет
это был всего лишь пример, потому что из твоего вообще ничего не понятно: что, где, куда и как.

cделай так
Код: plaintext
1.
2.
3.
4.
void OnClick(...)
{
	::SetLastError(ERROR_SINGLE_INSTANCE_APP);
}


если для тебя это принципиально
...
Рейтинг: 0 / 0
21.10.2012, 13:48
    #38007215
spyker
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
Cerebrum,

ну вот смотри:
поток таков:
Код: plaintext
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.
DWORD WINAPI SPEED(LPVOID pParam)
{
	Cgrafic1Dlg *ob=(Cgrafic1Dlg*)pParam;
...
	do {
		if(WaitForSingleObject(ob->hLockDataTh,20)==WAIT_OBJECT_0)
		{

			.....

			if(WaitForSingleObject(ob->h_EXIT,20)==WAIT_OBJECT_0)

			{
				SetEvent(ob->h_EXIT);
				break;
			}
			HANDLE hMutex=CreateMutex( NULL, FALSE, L"grafic1" );
			if(GetLastError() == ERROR_SUCCESS)
			{
			
			ob->g_hInstancesMutex = hMutex;
		
			}
			return ERROR_SINGLE_INSTANCE_APP;
		}

	}
	while(1);


	return 0;
};



кнопка старта:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
void Cgrafic1Dlg::OnBnClickedButton1()
{
	Invalidate();
	UpdateData(true);
	if(start) {
		ResumeThread(hThread);
		start=false;}

	ResetEvent(h_EXIT);
	hThread=CreateThread(NULL,0,&SPEED,this,0,&id);
	::SetLastError(ERROR_SINGLE_INSTANCE_APP);



}



вот так вот чтоли сделать?
...
Рейтинг: 0 / 0
21.10.2012, 14:32
    #38007248
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
spykerа этот код нужно в потоке писать лучше?
Нет, этот код нужно писать прямо в начале функции WinMain().
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
21.10.2012, 14:44
    #38007256
spyker
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
Dimitry Sibiryakov,

в какой главной функции winmain()
вот это не пойму
...
Рейтинг: 0 / 0
21.10.2012, 14:47
    #38007257
spyker
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
ну так и ничего не происходить, повторно приложения запускаются
...
Рейтинг: 0 / 0
21.10.2012, 15:18
    #38007279
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
В рот мне ноги, что это ?

Так. Давай с начала.

Как я понял поставленную задачу:

1. Есть программа, которая при нажатии на кнопку должна запустить поток (ThreadA).
2. Поток ThreadA должен проверить НЕ запущен ли уже другой аналогичный поток.
3. Если аналогичный поток запущен, то поток ThreadA завершает свою работу.
4. Если аналогичный поток НЕ запущен, ThreadA запускается создает объект мьютекс и поток делает то, что должен.

Я правильно понял твою задачу?

Если да, то

Код: plaintext
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.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
DWORD WINAPI SPEED(LPVOID pParam);

class Cgrafic1Dlg : public CDialog
{
private:
	HANDLE m_hThread;
	HANDLE m_hMutex; // ? нафиг он вообще тебе нужен

public:
	BOOL IsThreadRunning(void)
	{
		if (m_hThread)
		{
			DWORD dwExitCode;
			if (::GetExitCodeThread(m_hThread, &dwExitCode))
				return (dwExitCode == STILL_ACTIVE);
			::MessageBox(m_hWnd, _T("Шеф! Все пропало!"), ...);
		}
		return FALSE;
	}

	HANDLE GetWorkingThread(void) const { return m_hThread; }
	HANLDE SetWorkingThread(HANDLE hThread)
	{
		HANDLE hOldThread = m_hThread;
		::CloseHandle(m_hThread);	// ?
		m_hThread = hThread;
		return hOldThread;
	}

	void OnBnClickedButton1();
};

void Cgrafic1Dlg::Cgrafic1Dlg()
{
	m_hThread	= NULL;
	m_hMutex	= NULL;
}

void Cgrafic1Dlg::OnBnClickedButton1()
{
	if (m_hThread == NULL) // ничего не выполняется
	{
		HANDLE hThread = (HANDLE) _beginthreadex(NULL, 0, &SPEED, (void*)this, CREATE_SUSPENDED, NULL);
		if (hThread)
		{
			SetWorkingThread(hThread);
			::ResumeThread(m_hThread);
		}
		else
			::MessageBox(m_hWnd, _T("Гипс снимают!"), ...);
	}
	else	// что-то выполняется
	{
		if (IsThreadRunning() == FALSE)
		{
			SetWorkingThread(NULL); // кто-то забыл смыть в туалете
			OnBnClickedButton1();	  // try again ?
		}
		else
			::MessageBox(m_hWnd, _T("А нам все равно!"), ...);
	}
}

UINT WINAPI SPEED(LPVOID pParam)
{
...
	// выкини отсюда все что касается проверок повторного запуска
...
}
...
Рейтинг: 0 / 0
21.10.2012, 15:55
    #38007291
spyker
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
Cerebrum, немного не так
1. есть поток thread
2. я его запускаю
3. при запущенном потоке я иду в дебаг и запускаю grafic1.exe(как только я его запущу, у меня должно выжаться сообщение что поток запущен и не запускать приложение)

вот как бы так
...
Рейтинг: 0 / 0
21.10.2012, 16:08
    #38007302
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
spykerв какой главной функции winmain()
вот это не пойму
Есть только одна главная функция WinMain. Нажми F1 и прочитай.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
21.10.2012, 18:14
    #38007381
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
spyker,

Код: plaintext
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.
#pragma data_seg("Shared")
LONG g_nInstances = 0;					// счетчик экземпляров
#pragma data_seg()
#pragma comment(linker, "/Section:Shared,RWS")	// не разделять запятую пробелом !

UINT WINAPI SPEED(LPVOID pParam)
{
	ASSERT(g_nInstance == 0);
	DWORD dwResult = ERROR_SUCCESS;
	::InterlockedIncrement(&g_nInstances);
	__try
	{
		....// твой код
	} 
	__finally
	{
		if (g_nInstances > 0)
			::InterlockedDecrement(&g_nInstances);
	}
	return dwResult;
}

void Cgrafic1Dlg::OnBnClickedButton1()
{
	if (g_nInstances == 0)
	{
		HANDLE hThread = (HANDLE) _beginthreadex(NULL, 0, &SPEED, (void*)this, CREATE_SUSPENDED, NULL);
		if (hThread)
		{
			::ResumeThread(hThread);
		}
	}
	else
		::MessageBox(m_hWnd, _T("Мэ и Жо"),  ...);
}
...
Рейтинг: 0 / 0
21.10.2012, 18:50
    #38007412
spyker
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
Cerebrum,
...
Рейтинг: 0 / 0
21.10.2012, 18:51
    #38007413
spyker
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
похоже на обработчик исключений, а почему вместо catch -> __finally
...
Рейтинг: 0 / 0
21.10.2012, 18:55
    #38007423
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
spykerпохоже на обработчик исключений, а почему вместо catch -> __finally
Чтобы счетчик отматывать, тынц
...
Рейтинг: 0 / 0
21.10.2012, 19:51
    #38007455
spyker
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
проверка на запуск потока
Cerebrum,

спасибо!)
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / проверка на запуск потока / 22 сообщений из 22, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]