Molniev
Junior Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору Pikachupp Судя по константам аля-THREAD_PRIORITY_ABOVE_NORMAL программы вам с WinAPI: Л.Р.1 Вариант №5 ------------ Разработать две программы. Первая принимает от пользователя две строки. Далее, если обе строки хранят целые числа со знаком, то на экран выводится сумма чисел, в противном случае – конкатенация двух введенных строк. Вторая программа запускает первую в качестве вновь созданного процесса. Программа 2 (Запускающая) Код: #include <windows.h> int main(int argc, char* argv[]) { ShellExecuteW(0, NULL, L"prog.exe", NULL, NULL, SW_NORMAL); //ShellExecute - функция оболочки return 0; } | //где prog.exe - имя первой программы, находящейся в том же каталоге (папке) Программа 1 (Делающая много полезнова) Код: //У меня есть подозрения, что под строками вы понимате нечто вроде char*, а не std::wstring, так что C Style вариант вашего задания #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <windows.h> int main(int argc, char* argv[]) { char str1[256], str2[256]; int numb1, numb2; printf("Enter strings: \n"); scanf("%s %s", str1, str2); numb1 = atoi(str1); //функция atoi переводит строку str1 в число numb1, если str1 представляет собой не число (т.е. не "-15" а "абв"), то numb1 присваиваеться ноль numb2 = atoi(str2); if ( (0 == numb1 && '0' != str1[0]) || (0 == numb2 && '0' != str2[0]) ) //Если numb(1,2) ноль, а в самой строке не ноль - то в строке содержиться нечисловое значение. Ну кроме "-0". Добавте в проверку, если считаете это нужным. printf("%s%s\n", str1, str2); //В задании написано вывести контекацию строк, а не зделать её. Полное соответствие заданию. else printf("%i\n", numb1 + numb2); getchar(); getchar(); //может статься вам хватит и одного return 0; } | Л.Р.2 Вариант №5 ------------ Разработать программу, осуществляющую ввод двух строк, введенных пользователем. Далее, если обе строки хранят целые числа со знаком, то на экран выводится сумма чисел, в противном случае – конкатенация двух вве-денных строк. Проверку на соответствие строки целому числу, вычисление суммы чисел и конкатенации строк оформить как три разных функции потока. Ввод строк осуществляется до запуска всех потоков, а вывод результатов – после их завершения. Код: //По аналогии: #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <windows.h> typedef struct _workerset { char str1[256], str2[256]; int numb1, numb2; HANDLE verify_complit; BOOL isNumber; char result[256]; } workerset, *pworkerset; DWORD WINAPI verify_number(LPVOID lpThreadParameter) //функция проверки введенных строк на предмет их "численности" { pworkerset ws = (pworkerset)lpThreadParameter; //Получаем переданные в поток данные ws->numb1 = atoi(ws->str1); ws->numb2 = atoi(ws->str2); if ( (0 == ws->numb1 && '0' != ws->str1[0]) || (0 == ws->numb2 && '0' != ws->str2[0]) ) ws->isNumber = FALSE; else ws->isNumber = TRUE; //Аналогично первой программе, только флаг ставим в общей для всех потоков структуре SetEvent(ws->verify_complit); //Выставляем событие в сигнальное состояние (TRUE), потоки sum_number и sum_string в строке WaitForSingleObject размараживаються и продолжают тяжкую работу return 0; } DWORD WINAPI sum_number(LPVOID lpThreadParameter) { pworkerset ws = (pworkerset)lpThreadParameter; WaitForSingleObject(ws->verify_complit, INFINITE); //Ждем пока поток verify_number не заполнит переменные ws->isNumber, ws->numb1, ws->numb2 if (ws->isNumber) sprintf(ws->result, "%i\n", ws->numb1 + ws->numb2); //Результат выводиться "а вывод результатов – после их завершения" такчто пишем его во временую переменную return 0; } DWORD WINAPI sum_string(LPVOID lpThreadParameter) { pworkerset ws = (pworkerset)lpThreadParameter; WaitForSingleObject(ws->verify_complit, INFINITE); //Ждем пока поток verify_number не заполнит переменныю ws->isNumber if (! ws->isNumber) sprintf(ws->result, "%s%s\n", ws->str1, ws->str2); //К слову говоря такое использование sprintf и есть контекация строк в чистом виде (ну только не штатной strcat, а более мощным вариантом) return 0; } int main(int argc, char* argv[]) { workerset ws; DWORD n = 0; HANDLE threads[3]; printf("Enter strings: \n"); scanf("%s %s", ws.str1, ws.str2); ws.verify_complit = CreateEventW(NULL, TRUE, FALSE, NULL); //Создаем событие, сию есть объект синхронизации threads[0] = CreateThread(NULL, 0, verify_number, &ws, 0, &n); threads[1] = CreateThread(NULL, 0, sum_number, &ws, 0, &n); threads[2] = CreateThread(NULL, 0, sum_string, &ws, 0, &n); WaitForMultipleObjects(3, threads, TRUE, INFINITE); //Ждем пока все потоки завершаться (читай отработают) printf("%s", ws.result); //Выводим результат //Ах да. Мы не закрываем хендлы - что в нормальных программах делать не в коем случае нельзя! Но у нас то учебная. getchar(); getchar(); return 0; } | Вариант №5 ------------ Разработать программу, осуществляющую ввод двух строк, введенных пользователем. Далее, если обе строки хранят целые числа со знаком, то на экран выводится сумма чисел, в противном случае – конкатенация двух вве-денных строк. Проверку на соответствие строки целому числу, вычисление суммы чисел и конкатенации строк оформить как три разных функции потока (с приоритетами, соответственно, THREAD_PRIORITY_ABOVE_NORMAL, HREAD_PRIORITY_LOWEST и THREAD_PRIORITY_IDLE). Ввод строк осуществляется до запуска всех по-токов, а вывод результатов – после их завершения. Также выводятся значе-ния времени работы каждого потока. //Тоже самое, что и предыдушая программа, только вместо старого main, такой и ещё функция вывода времени перед ним //Так-как потоки у нас ничего особо не делают то время может выйти по нулям. Дабы показать, что все это хозяйство работает и время таки считает, то в одну из функций советую впихнуть нечто вроде Sleep(1000); и ротацией односекундного (1000 - это тысяча милисекунд) интервала на другие значения и соответствующим изменениев времени выполнения потока куда это дело было впихнуто (или всех трех, если в verify_number выше SetEvent) демонстрировать так сказать преподовательскому составу этот подсчет. Код: void print_worktime(HANDLE thread_handle, char *thread_name) { FILETIME ft[3]; float d; GetThreadTimes(thread_handle, &ft[0], &ft[1], &ft[2], &ft[2]); ft[1].dwLowDateTime -= ft[0].dwLowDateTime; ft[1].dwHighDateTime -= ft[0].dwHighDateTime; //по хорошему мы тут должны учесть переполнение младшего dword-а, но бог с ним d = (float)ft[1].dwLowDateTime / 10000000; //тутачки время из 100 наносекундных интервалов в секунды скидываем printf("%s work time: %f\n", thread_name, d); } int main(int argc, char* argv[]) { workerset ws; DWORD n = 0; HANDLE threads[3]; printf("Enter strings: \n"); scanf("%s %s", ws.str1, ws.str2); ws.verify_complit = CreateEventW(NULL, TRUE, FALSE, NULL); threads[0] = CreateThread(NULL, 0, verify_number, &ws, 0, &n); threads[1] = CreateThread(NULL, 0, sum_number, &ws, 0, &n); threads[2] = CreateThread(NULL, 0, sum_string, &ws, 0, &n); SetThreadPriority(threads[1], THREAD_PRIORITY_LOWEST); SetThreadPriority(threads[2], THREAD_PRIORITY_IDLE); WaitForMultipleObjects(3, threads, TRUE, INFINITE); printf("%s", ws.result); print_worktime(threads[0], "verify_number"); print_worktime(threads[1], "sum_number"); print_worktime(threads[2], "sum_string"); getchar(); getchar(); return 0; } | cp58 Информирую, pthread нету (ну окромя эмуляции/трансляции через либы cydwin/mingw). Есть либо через штатное api - CreateThread, либо через сишные потоки (beginthread или что то в этом роде). Ну сами то потоки не беда, вызовы что в winAPI что в pthread различаються непринципиально. А вот с примитивами синхронизации сложней - тут есть некоторые идеологические различия. Добавлено: Pikachupp Ах да, забыл дописать. В третей программе мы не маемся дурью и приоритет THREAD_PRIORITY_ABOVE_NORMAL никому не задаём - ибо он задается самой системой при создании потока. Ну это для справки - если вдруг такой каверзный вопрос возникнет. |