////////////////////////////////////////////////////////////////////////////// // Function : The Publication part of the APPLICATION_DEMO Task // Description : Simulates Publishing , ReadCommand & CommandResponse ////////////////////////////////////////////////////////////////////////////// void APP_publicationProc( uint8_t p_ucCrtEvent ) { int nLen; #if defined(METER_BOARD) if( p_ucCrtEvent & PUBLISH_REQ_EVENT ) { LockSemaphore(&g_stMeterControlLock); if (g_stMeterTableToRead.data_length == 0) { if (meter_last_connect_error_code) nLen = sprintf(g_stRspPacket.m_aBuff,"<value at =\'%d\'>C%04X</value>",(int) os_adapt_time(), meter_last_connect_error_code); // connect error code else if (meter_last_periodic_read_error_code) nLen = sprintf(g_stRspPacket.m_aBuff,"<value at =\'%d\'>R%04X</value>",(int) os_adapt_time(), meter_last_periodic_read_error_code); // read error code else if (meter_last_disconnect_error_code) nLen = sprintf(g_stRspPacket.m_aBuff,"<value at =\'%d\'>D%04X</value>",(int) os_adapt_time(), meter_last_disconnect_error_code); // disconnect error code else nLen = sprintf(g_stRspPacket.m_aBuff,"<value at =\'%d\'> </value>",(int) os_adapt_time()); // nothing } else { nLen = sprintf(g_stRspPacket.m_aBuff,"<value at =\'%d\'>", (int) os_adapt_time() ); for (int i = 0; (i < g_stMeterTableToRead.data_length) && (nLen < (sizeof(g_stRspPacket.m_aBuff) - 16)); i++) { nLen += sprintf(g_stRspPacket.m_aBuff + nLen, "%02X", g_stMeterTableToRead.table_data[i]); // hex } nLen += sprintf(g_stRspPacket.m_aBuff+nLen,"</value>" ); g_stMeterTableToRead.data_length = 0; } UnlockSemaphore(&g_stMeterControlLock); C_NLOG_INFO(g_stRspPacket.m_aBuff); APP_udp_send_to( g_hPubSocket, (const unsigned char*)g_stRspPacket.m_aBuff, nLen,g_stPeristsApp.m_unPublishDstIp6Addr, g_stPeristsApp.m_unPublishDstPort ); } #endif if ( (uint32_t)(os_adapt_time() - g_ulLastTime) > (uint32_t)g_nPubTimeAlloc ) { g_TestPub++; // BUILD PACKET #if defined(MOTION_DETECTION_BOARD) nLen = sprintf(g_stRspPacket.m_aBuff,"<value at =\'%d\'>%d</value>",(int) os_adapt_time(), g_ulValue ); C_NLOG_INFO(g_stRspPacket.m_aBuff); APP_udp_send_to( g_hPubSocket, (const unsigned char*)g_stRspPacket.m_aBuff, nLen,g_stPeristsApp.m_unPublishDstIp6Addr, g_stPeristsApp.m_unPublishDstPort ); #elif defined(METER_BOARD) APP_readDemandValue(); // will signal meter task to start readings #else uint32_t nPublishValue = APP_readDemandValue(); nLen = sprintf( g_stRspPacket.m_aBuff, "<value at =\'%d\'>%d</value>", (int) os_adapt_time(), nPublishValue ); C_NLOG( "APP_node: %s", g_stRspPacket.m_aBuff ); APP_udp_send_to( g_hPubSocket, (const unsigned char*)g_stRspPacket.m_aBuff, nLen, (const TIpv6Addr*)g_stPeristsApp.m_unPublishDstIp6Addr, g_stPeristsApp.m_unPublishDstPort ); #endif g_ulLastTime = os_adapt_time(); } }
// Working flow of evolution void GaMultithreadingAlgorithm::WorkFlow() { // give ID to worker thread int workerId = ATOMIC_INC( _workerIdCounter ) - 1; while( 1 ) { // wait for command from control thread LockSemaphore( _workerForkSync ); // stop the thread to apply parameter change if( _parametersChange ) break; // execute work step if the algorithm is not stopped if( _state == GAS_RUNNING ) WorkStep( workerId ); // only the last worker will releast the others to continue if( !ATOMIC_DEC( _workersThreadIn ) ) UnlockSemaphore( _workerJoinSync, _numberOfThreads - 1 ); // wait for the last worker to reach this point before notifying control thread LockSemaphore( _workerJoinSync ); // the last worker thread to exit notifies control thread that work step is done if( !ATOMIC_DEC( _workersThreadOut ) ) SignalEvent( _controlSync ); // algorithm is stopped if( _state != GAS_RUNNING ) break; } }
//======================================================================== int main() { pid_t pid; int semid; semid = CreateSemaphore(1); SetSemaphoreValue(semid, 0, 1); pid = fork(); if(pid==0) //child 1 { sleep(1); int res; res = LockSemaphore(semid, 0); /* Try LockSemaphore的用法 res = EAGAIN; while(res== EAGAIN) { res= TryLockSemaphore(semid, 0, 1000); //设置1000ms超时 //do something } */ printf("child 1 set[%d]....\n",res); // do critical things sleep(10); UnlockSemaphore(semid, 0); printf("child 1 post[%d]....\n",res); return 0; } int dd; dd = LockSemaphore (semid, 0); printf("parent set 1[%d]....\n",dd); sleep(10); dd = UnlockSemaphore(semid, 0); //sleep(2); printf("parent end: ...[%d]\n",dd); //FreeSemaphore(semid); UnlockSemaphore(semid, 0); }
// Control flow of evolution void GaMultithreadingAlgorithm::ControlFlow() { while( 1 ) { // now parameters and state cannot be changed BlockParameterChanges(); BlockStateChange(); int count = ( (const GaMultithreadingAlgorithmParams&) GetAlgorithmParameters() ).GetNumberOfWorkers(); if( _state == GAS_RUNNING ) // execute control step before workers BeforeWorkers(); // release working threads _workersThreadOut = _workersThreadIn = count; UnlockSemaphore( _workerForkSync, count ); // wait for working threads to finish the job WaitForEvent( _controlSync ); // still running? if( _state != GAS_RUNNING ) { // stop the threads // now it safe to change parameters and state ReleaseParameterChanages(); ReleaseStateChange(); break; } // execute control step after workers AfterWorkers(); // stop algorithm is criteria is reached CheckStopCriteria(); // now it safe to change parameters and state ReleaseStateChange(); ReleaseParameterChanages(); } }
int main(int argc, char *argv[]) { int* queuePtr; int producersDone = 0, consumersDone = 0; int i = 0, j = 0; int status; int itemsConsumed = 0; int* itemsConsumedPtr; short sems[3]; int semid; key_t key = 4590; int fullSem = 0, emptySem = 0, accessSem = 0; struct sembuf arg; //assume first argument is the application name if (argc < 4) { printf("Error: Invalid input"); exit(0); } //Gets CLI Values. Tanks if values not provided. for (i = 1; i < argc; i++) { //printf("CLI Value:%s\n", argv[i]); SetCLIValues(argv[i], i); } //indicates the total number of items to be created. totalItems = producerCount * itemCount; printf("Using %d producers to produce %d items\n", producerCount, totalItems); //gets the requisite set of allocated memory for producers and consumers //to pump data into/out of. if ((sharedMemId = shmget(IPC_PRIVATE, (queueSize + 2) * sizeof(int), 0660)) == -1) { //implement fallout for shmget failure } printf("allocating %d ints at shared memory id %d\n", queueSize, sharedMemId); //gets a pointer to the allocated memory if ((sharedMemPtr = (int *) shmat(sharedMemId, (void *) 0, 0)) == (void *) -1) { //implement fallout for shmgat failure } //sets the queue to point to the shared memory queuePtr = sharedMemPtr; //initialize queue to -1; for (i = 0; i < queueSize; i++) { queuePtr[i] = -1; } //total items consumed queuePtr[queueSize] = 0; //total items produced queuePtr[queueSize + 1] = 0; sems[QUEUE_FULL] = 0; sems[QUEUE_EMPTY] = 1; sems[QUEUE_ACCESS] = 2; //Allocate Semaphore. Gets Semaphore ID if ((semid = semget(key, 3, 0600 | IPC_CREAT)) == -1) { printf("error getting semaphore\n"); exit(1); } else { printf("Allocated 3 Semaphores at semaphore ID:%d\n", semid); } semctl(semid, 0, SETALL, sems); fullSem = sems[QUEUE_FULL]; emptySem = sems[QUEUE_EMPTY]; accessSem = sems[QUEUE_ACCESS]; UnlockSemaphore(semid, emptySem); UnlockSemaphore(semid, fullSem); UnlockSemaphore(semid, accessSem); LockSemaphore(semid, emptySem); //generates an array of consumers and producers. pid_t prodIds[producerCount]; pid_t consIds[consumerCount]; //for producer processes for (i = 0; i < producerCount; i++) { switch (prodIds[i] = fork()) { case -1: printf("Error forking producer\n"); break; case 0: //printf("producer created with id=%d, pid=%d\n", prodIds[i], // getpid()); // printf("Queue Full Semaphore: %d\n", semctl(semid, fullSem, GETVAL, arg.sem_num)); for (i = 0; i < itemCount; i++) { int hasAddedToQueue = 0; while (hasAddedToQueue == 0) { //if queue isn't full, addd something to queue; //put something into the queue //loop through queue to find an empty spot //as indicated by the value = -1 //check to see if the queue is available if (semctl(semid, fullSem, GETVAL, arg.sem_num) > 0) { while (semctl(semid, accessSem, GETVAL, arg.sem_num) <= 0) { usleep(waitTime); } //lock semaphore LockSemaphore(semid, accessSem); //if it is, do the do. for (j = 0; j < queueSize; j++) { if (queuePtr[j] == -1) { if (queuePtr[queueSize + 1] >= totalItems) { // printf("Completed Producing %d items", // totalItems); // printf("exiting producer"); exit(0); } //do your stuff queuePtr[j] = itemsProduced; queuePtr[queueSize + 1]++; printf( "%d\t%d\t%d\t%d\t%d\t%d\t%s\t%d\t%d\t\n", getpid(), 0, 1, semctl(semid, emptySem, GETVAL, arg.sem_num), semctl(semid, fullSem, GETVAL, arg.sem_num), semctl(semid, accessSem, GETVAL, arg.sem_num), "Produce", queuePtr[queueSize+1], queuePtr[queueSize]); //unlock it itemsProduced++; hasAddedToQueue = 1; fullCount++; emptyCount--; j = queueSize; } if (semctl(semid, emptySem, GETVAL, arg.sem_num) <= 0) { UnlockSemaphore(semid, emptySem); } } UnlockSemaphore(semid, accessSem); //if the queue is full, lock the queue if (fullCount == queueSize || hasAddedToQueue == 0) { hasAddedToQueue = 1; //LockSemaphore(semid, fullSem); } } else { usleep(waitTime); } } } //printf("Exiting Producer Process %d\n", getpid()); exit(EXIT_SUCCESS); break; case 1: printf("producer parent process ID %d\n", getpid()); //waits around for child processes to get done. if ((prodIds[i] = wait(&status)) == -1) { perror("error waiting for children to complete.\n"); } else { printf("Child process ended normally.n"); producersDone = 1; } break; } } for (i = 0; i < consumerCount; i++) { switch (consIds[i] = fork()) { case -1: printf("Error forking consumer\n"); break; case 0: printf("consumer created with id=%d, pid=%d, parent pid=%d\n", consIds[i], getpid(), getppid()); printf("Queue Empty: %d\n", semctl(semid, emptySem, GETVAL, arg.sem_num)); //consume until total number of items have been consumed while (queuePtr[queueSize] < totalItems) { //if queue is empty, wait around until something comes into it. if (semctl(semid, emptySem, GETVAL, arg.sem_num) > 0) { //consume item. int foundValue = 0; while (semctl(semid, accessSem, GETVAL, arg.sem_num) <= 0) { usleep(waitTime); } LockSemaphore(semid, accessSem); for (j = 0; j < queueSize; j++) { if (queuePtr[j] != -1) { //print out consumer queuePtr[queueSize]++; printf( "%d\t%d\t%d\t%d\t%d\t%d\t%s\t%d\t%d\t\n", getpid(), 0, 1, semctl(semid, emptySem, GETVAL, arg.sem_num), semctl(semid, fullSem, GETVAL, arg.sem_num), semctl(semid, accessSem, GETVAL, arg.sem_num), "Consume", queuePtr[queueSize+1], queuePtr[queueSize]); queuePtr[j] = -1; //increments total items consumed emptyCount++; foundValue = 1; if (semctl(semid, fullSem, GETVAL, arg.sem_num) <= 0) { UnlockSemaphore(semid, fullSem); } if (queuePtr[queueSize] >= totalItems) { if (queuePtr[queueSize] == totalItems) { printf( "All consumption has been completed.\n"); } //printf("Exiting Consumer Thread %d", getpid()); exit(0); //all consumption is done. } j = queueSize; } } UnlockSemaphore(semid, accessSem); if (fullCount <= 0 || foundValue == 0) { //LockSemaphore(semid, emptySem); } } else { usleep(waitTime); } } printf("Exiting Consumer Process %d\n", getpid()); break; case 1: printf("consumer parent process ID %d\n", getpid()); //waits around for child processes to get done. if (waitpid(prodIds[i], &status, WUNTRACED) == -1) { perror("error waiting for children to complete.\n"); } else if (WIFEXITED(status) != 0) { printf("Child process ended normally; status = %d.n", WEXITSTATUS(status)); consumersDone = 1; } break; } } //printf("Allocated %d semaphores with id: %d\n", queueSize, semid); // printf("press any key to deallocate semaphore\n" ); // getchar(); // for (i = 0; i < producerCount; i++) { // if (waitpid(prodIds[i], &status, 0) == -1) // printf("Error exiting child process"); // // } // for (i = 0; i < consumerCount; i++) { // if (waitpid(consIds[i], &status, 0) == -1) // printf("Error exiting child process"); // // } while (wait(&status) > 0) //deallocate shared memory shmdt(sharedMemPtr); //delete allocated semaphores semctl(semid, 0, IPC_RMID); //printf("Deallocated Semaphore\n"); return 0; }
// Sets new parameters for algorithm void GaMultithreadingAlgorithm::SetAlgorithmParameters(const GaAlgorithmParams& parameters) { int newCount = ( (const GaMultithreadingAlgorithmParams&)parameters ).GetNumberOfWorkers(); // state of algorithm couldnot be changed during parameter change BlockStateChange(); int oldCount = _numberOfThreads - 1; // nothing changed? if( oldCount == newCount ) { // now it safe to change state of algorithm ReleaseStateChange(); return; } // if algorithm is running - stop all worker threads if( _state == GAS_RUNNING ) { _parametersChange = true; // release working threads _workersThreadOut = _workersThreadIn = oldCount; UnlockSemaphore( _workerForkSync, oldCount ); // wait for working threads to be closed for( int i = 1; i <= oldCount; i++ ) _threads[ i ]->Join(); _parametersChange = false; } // remove synchronization objects DeleteSemaphore( _workerForkSync ); DeleteSemaphore( _workerJoinSync ); // make new synchronization object MakeSemaphore( _workerForkSync, newCount, 0 ); MakeSemaphore( _workerJoinSync, newCount, 0 ); // new thread pool GaThread** newThreads = new GaThread*[ newCount + 1 ]; // copy old needed threads int lim = min( oldCount, newCount ) + 1; for( int i = 0; i < lim; i++ ) newThreads[ i ] = _threads[ i ]; if( oldCount < newCount ) { // new threads should be added // new worker threads' parameters GaThreadParameter p; p._functionPointer = WorkFlowWrapper; p._functionParameters = this; // make new threads for( int i = newCount - oldCount + 1; i < newCount; i++ ) newThreads[ i ] = new GaThread( p, false ); } else { // threads should be remove // free old threads for( int i = oldCount - newCount + 1; i < oldCount; i++ ) delete _threads[ i ]; } // swap pool of threads delete[] _threads; _threads = newThreads; _numberOfThreads = newCount + 1; // restart working threads if they were running if( _state == GAS_RUNNING ) { for( int i = 1; i <= newCount; i++ ) _threads[ i ]->Start(); } // now it safe to change state of algorithm ReleaseStateChange(); }