/******************************************************************************/ /** @file "Pthreads/C/Ispitni zadaci/si4mps_k1_20072008_z5.c" @brief Pronalazenje minimuma i maksimuma u nizu celih brojeva. @author Nepoznat */ /******************************************************************************/ // Ovo je samo jedno od mnogih mogućih rešenja zadatka #include #include const int NUM_THREADS = 5; void CreateAndLoadArray(int* &p_numbers, size_t& p_count) { std::cout << "Unesite broj elemenata niza: "; std::cin >> p_count; p_numbers = new int[p_count]; if (NULL != p_numbers && p_count >= NUM_THREADS) { std::cout << "Unesite elemente niza: "; for (size_t index = 0; index < p_count; index++) { std::cin >> p_numbers[index]; } } else { p_numbers = NULL; p_count = 0; } } typedef struct results { int minimum; int maximum; } Results; Results results; typedef struct thread_data { int *m_elements; size_t m_base; size_t m_endOffset; pthread_mutex_t *m_lockAddr; } ThreadData; void print_results(Results results) { printf("Min: %d, max: %d\n", results.minimum, results.maximum); } void* work_routine(void *pData) { // sve što je uslovljeno sa PTW32_STATIC_LIB je potrebno // samo za pthreads-win32 i to samo u static linked varijanti #ifdef PTW32_STATIC_LIB pthread_win32_thread_attach_np(); { #endif unsigned i; int localMin, localMax; ThreadData *pThreadData = (ThreadData*) pData; // kvadriraj elemente i traži lokalni maksimum localMin = localMax = pThreadData->m_elements[pThreadData->m_base]*pThreadData->m_elements[pThreadData->m_base]; for (i = pThreadData->m_base; i < pThreadData->m_endOffset; i++) { pThreadData->m_elements[i] *= pThreadData->m_elements[i]; if (localMin > pThreadData->m_elements[i]) { localMin = pThreadData->m_elements[i]; } if (localMax < pThreadData->m_elements[i]) { localMax = pThreadData->m_elements[i]; } } // uporedi lokalni maksimum sa globalnim maksimumom pthread_mutex_lock(pThreadData->m_lockAddr); if (localMin < results.minimum) { results.minimum = localMin; } if (localMax > results.maximum) { results.maximum = localMax; } pthread_mutex_unlock(pThreadData->m_lockAddr); // sve što je uslovljeno sa PTW32_STATIC_LIB je potrebno // samo za pthreads-win32 i to samo u static linked varijanti #ifdef PTW32_STATIC_LIB } pthread_win32_thread_detach_np(); #endif // pthread_exit(NULL); nije neophodno pošto će implicitno biti pozvano return 0; } int main() { // sve što je uslovljeno sa PTW32_STATIC_LIB je potrebno // samo za pthreads-win32 i to samo u static linked varijanti #ifdef PTW32_STATIC_LIB pthread_win32_process_attach_np(); pthread_win32_thread_attach_np(); { #endif // niz i broj elemenata int *elements; size_t elementCount; unsigned i; size_t sliceSize; ThreadData threadData[NUM_THREADS]; pthread_t workers[NUM_THREADS]; pthread_attr_t attributes; pthread_mutex_t lock; CreateAndLoadArray(elements, elementCount); if (0 != elementCount) { pthread_attr_init(&attributes); pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE); pthread_mutex_init(&lock, NULL); results.minimum = results.maximum = elements[0] * elements[0]; for (i = 0; i < NUM_THREADS; i++) { threadData[i].m_elements = elements; threadData[i].m_lockAddr = &lock; sliceSize = elementCount / NUM_THREADS; threadData[i].m_base = sliceSize * i; /* poslednja nit dobija eventualne viškove */ if (NUM_THREADS - 1 == i) { sliceSize += elementCount % NUM_THREADS; } threadData[i].m_endOffset = threadData[i].m_base + sliceSize; pthread_create(&workers[i], NULL, work_routine, (void*) (threadData + i) ); } // atributi postaju nepotrebni nakon što se stvaranje niti završi pthread_attr_destroy(&attributes); for (i = 0; i < NUM_THREADS; i++) { pthread_join(workers[i], NULL); } print_results(results); pthread_mutex_destroy(&lock); delete [] elements; } // sve što je uslovljeno sa PTW32_STATIC_LIB je potrebno // samo za pthreads-win32 i to samo u static linked varijanti #ifdef PTW32_STATIC_LIB } pthread_win32_thread_detach_np(); pthread_win32_process_detach_np(); #endif }