Процессы (С++ под Windows)
Выглядеть должно примерно так:
Включаем программу->вводим число-запускается процесс(во время работы будет выглядеть как 1 2 3 4 5 ....)->нажимаем некую клавишу(допустим 1) и процесс перестает выводить цифры.
PS: Программа простенькая, но совершенно не разбираюсь в процессах, может быть кто-нибудь подскажет где можно об этом почитать.
Я так понял, автор темы имеет ввиду под "процессом" Поток.
Процессы тут не при чем.
Прочитайте С++ многопоточность
http://www.cyberguru.ru/programming/cpp/multithreading-intro.html
Общая схема такая:
{
DWORD dwThread[100];
HANDLE hThread[100];
int i, trid = 0;
unsigned char param[1000];
while (trid < 100)
{
hThread[trid] = CreateThread(NULL,0,threadwork,param+trid,0,&dwThread[trid]);
trid++;
}
for (i = 0;i < trid;i++) {
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
}
return 0;
}
DWORD CALLBACK threadwork (char *argv)
{
// код потока
return 0;
}
Процессы тут не при чем.
Может, задание состоит в том, чтобы вывод в консоль выполнялся из дочернего процесса. Вполне может быть.
Тогда читать MSDN на тему CreateProcess, и гуглить на "синхронизация процессов в windows".
А еще лучше почитать книжку ( даже на русском:) ) "Рихтер Дж. — Windows для профессионалов: создание эффективных Win32 приложений с учетом специфики 64-разрядной версии Windows". Там все просто, полезно и понятно.
Общая схема такая:
hThread[trid] = CreateThread(NULL,0,threadwork,param+trid,0,&dwThread[trid]);
//...
DWORD CALLBACK threadwork (char *argv) {
// ...
}
Вот здесь вы немножко неправы, в общей схеме функция threadwork должна принимать указатель на void:
char *func_param = param + trid;
hThread[trid] = CreateThread(NULL, 0, threadwork, (void *)func_param, 0, &dwThread[trid]);
// ...
DWORD WINAPI threadwork(void *argv) {
char *some_string = (char *)argv;
//...
}
Тогда читать MSDN на тему CreateProcess, и гуглить на "синхронизация процессов в windows".
А еще лучше почитать книжку ( даже на русском:) ) "Рихтер Дж. — Windows для профессионалов: создание эффективных Win32 приложений с учетом специфики 64-разрядной версии Windows". Там все просто, полезно и понятно.
Так и есть, и немного перепутал должно быть 2 процесса. 1 выводит начиная с 1 до n, а второй в обратном порядке, в другой половине консоля. Выводить должны одноврменно. Каким образом это можно ссинхронизирировать?
Думаю, проще всего мьютексами. Как - подробно описано у Рихтера, у гугла ("синхронизация процессов в windows"), и в MSDN на тему "mutex objects". Что не понятно - спрашивайте.
в 1 строчке консоля выводит от 1 до 10
во второй строчке консоля от 10 до 1
Не представляю(даже теоретически) как синхронизировтаь такое дело... Информации о мьютексах конечно много, но что-то не могу найти примеров в виде выполнения несколких одновременных задач.
Единственное что приходит на ум: Создается 2 процесса(представляют собой циклы вывода цифр). Далее каким то оброзом с помощью мьбютексов, сначало выводится 1 цифра в первой строке, перескакиваем на вторую строку, выводим символ из процесса 2 и т.д.
Ничего у вас спомощью мьютексов не будет выводиться. А вот синхронизоваться - да.
Никогда не интересовался компиляторо-зависимым форматированием в консоли, а вот синхронизацию можно сделать так:
{
HANDLE hMutex = ::CreateMutex(NULL/*lpMutexAttributes*/,bInitialOwner, lpMutexName);
for ( size_t i=0; i<50; i++ )
{
CGuard lock ( hMutex ); // занимаем блокировку, чтобы выводить в консоль монопольно
// вывод в консоль
cout << i << "; ";
}
}
void output2()
{
HANDLE hMutex = ::CreateMutex(NULL/*lpMutexAttributes*/,bInitialOwner, lpMutexName);
for ( size_t i=50; i>0; i-- )
{
CGuard lock ( hMutex ); // занимаем блокировку, чтобы выводить в консоль монопольно
// вывод в консоль
cout << i << "; ";
}
}
/* класс для блокировки-разблокировки. Преимужество то же, что и
в смарт-поинтерах, вам не нужно беспокоиться об освобождении
объёкта: он будет освобожден при выходе из области видимости
*даже* если возникнет исключение.
Иначе при использовании нескольких точек выхода из функции и
исключений получите кучу гемороя следить где что надо освободить */
class CGuard
{
public:
CGuard( HANDLE handleToLock )
: m_mutex( handleToLock )
{
// занимаем мьютекс, если он уже занят - принудительное ожидание
::WaitForSingleObject( m_mutex, INFINITE );
}
~CGuard( )
{
// освобождаем мьютекс, чтобы ег омог занять другой процесс/поток
::ReleaseMutex( m_mutex );
}
private:
HANDLE m_mutex;
};
}
То есть - прямо перед началом использования общего ресурса занимаем мьютекс, чтобы использовать его монопольно, после того, как "использовали" - освобождаем блокировку, чтобы другие потоки (или процессы) могли его использовать.