static ThreadPoolTask* sumbit(void* (*routine)(void*), void* param, int toFront) { if (threadPool == NULL) { routine(param); return NULL; } ThreadPoolQueue* queue = &(threadPool->queue); semaphoreWait(&(queue->mutex)); if (threadPool->terminated) { semaphorePost(&(queue->mutex)); return NULL; } if (queue->current == (queue->last + 1) % queue->maxLength) { queue->full = 1; semaphorePost(&(queue->mutex)); semaphoreWait(&(queue->wait)); semaphoreWait(&(queue->mutex)); } if (threadPool->terminated) { semaphorePost(&(queue->mutex)); return NULL; } ThreadPoolTask* task = (ThreadPoolTask*) malloc(sizeof(ThreadPoolTask)); task->routine = routine; task->param = param; semaphoreCreate(&(task->wait), 0); if (toFront) { queue->current = (queue->current - 1 + queue->maxLength) % queue->maxLength; queue->data[queue->current] = task; } else { queue->data[queue->last] = task; queue->last = (queue->last + 1) % queue->maxLength; } semaphorePost(&(queue->mutex)); semaphorePost(&(queue->submit)); return task; }
extern void threadPoolTaskWait(ThreadPoolTask* task) { if (task == NULL) { return; } semaphoreWait(&(task->wait)); semaphorePost(&(task->wait)); // unlock for double waiting }
void learnProcessSemaphores() { int sem_id = createSemaphore(); /*semaphorePost(sem_id);*/ semaphoreGetCount(sem_id); /*sleep(1000);*/ semaphoreWait(sem_id); semaphoreGetCount(sem_id); }
static void* worker(void* param) { ThreadPoolQueue* queue = &(threadPool->queue); while (1) { semaphoreWait(&(queue->submit)); if (threadPool->terminated) { break; } semaphoreWait(&(queue->mutex)); ThreadPoolTask* task = queue->data[queue->current]; queue->current = (queue->current + 1) % queue->maxLength; semaphorePost(&(queue->mutex)); if (threadPool->terminated) { semaphorePost(&(task->wait)); break; } task->routine(task->param); semaphorePost(&(task->wait)); semaphoreWait(&(queue->mutex)); if (queue->full && queue->current == queue->last) { queue->full = 0; semaphorePost(&(queue->wait)); break; } semaphorePost(&(queue->mutex)); } return NULL; }
extern void threadPoolTerminate() { if (threadPool == NULL) { return; } int i; ThreadPoolQueue* queue = &(threadPool->queue); semaphoreWait(&(queue->mutex)); threadPool->terminated = 1; // unlock all threads for (i = 0; i < threadPool->threadsLen; ++i) { semaphorePost(&(queue->submit)); } // unlock waiting on full queue semaphorePost(&(queue->wait)); semaphorePost(&(queue->mutex)); // wait for threads to be killed for (i = 0; i < threadPool->threadsLen; ++i) { threadJoin(threadPool->threads[i]); } // release all waiting on tasks for (i = queue->current; i != queue->last; ++i) { if (i == queue->maxLength) i = 0; semaphorePost(&(queue->data[i]->wait)); } semaphoreDelete(&(queue->wait)); semaphoreDelete(&(queue->submit)); semaphoreDelete(&(queue->mutex)); free(queue->data); free(threadPool->threads); free(threadPool); threadPool = NULL; }
int main(int argc, char const *argv[]) { if (argc != 2) { printf("usage: %s <data file>\n", argv[0]); exit(4); } int semaphores = getSemaphores(); semaphoreWait(semaphores, WRITER); FILE* outputFile; outputFile = fopen(argv[1], "w"); if (outputFile == 0) { printf("error: couldn't open output file"); exit(5); } StudentInfo* basePointer = getSharedMemoryPointer(); StudentInfo* currentPointer = basePointer; for (int i = 0; i < MAX_STUDENTS; ++i) { fprintf(outputFile, "%s\n", currentPointer->studentName); fprintf(outputFile, "%s\n", currentPointer->studentID); fprintf(outputFile, "%s\n", currentPointer->address); fprintf(outputFile, "%s\n", currentPointer->telephoneNumber); currentPointer++; } fclose(outputFile); detachSharedMemoryPointer(basePointer); destroySharedMemory(); destroyReadCount(); semaphoreSignal(semaphores, WRITER); destroySemaphores(semaphores); return 0; }