以前操作系统课程设计的时候,我们在Linux操作系统中用C语言和POSIX线程库编写过线程同步与互斥。
/* * thread_synchronization.c * * Copyright 2012 叶剑飞 * * 编译命令: * gcc thread_synchronization.c -o thread_synchronization \ * -std=gnu99 -pedantic-errors -D_REENTRANT -pthread -Wall * */ #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <pthread.h> #include <unistd.h> #include <semaphore.h> #include <time.h> typedef int COUNT; sem_t p12, p13, p24, p25, p35, p46, p56; int maxLoop[7]; void * thread1 ( void * args ) { for ( COUNT i = 0 ; i < maxLoop[1] ; i ++ ) { puts( "I am thread one." ); usleep(500000); } sem_post( &p12 ); sem_post( &p13 ); return NULL; } void * thread2 ( void * args ) { sem_wait( &p12 ); for ( COUNT i = 0 ; i < maxLoop[2] ; i ++ ) { puts( "I am thread two." ); usleep(500000); } sem_post( &p24 ); sem_post( &p25 ); return NULL; } void * thread3 ( void * args ) { sem_wait( &p13 ); for ( COUNT i = 0 ; i < maxLoop[3] ; i ++ ) { puts( "I am thread three." ); usleep(500000); } sem_post( &p35 ); return NULL; } void * thread4 ( void * args ) { sem_wait( &p24 ); for ( COUNT i = 0 ; i < maxLoop[4] ; i ++ ) { puts( "I am thread four." ); usleep(500000); } sem_post( &p46 ); return NULL; } void * thread5 ( void * args ) { sem_wait( &p25 ); sem_wait( &p35 ); for ( COUNT i = 0 ; i < maxLoop[5] ; i ++ ) { puts( "I am thread five." ); usleep(500000); } sem_post( &p56 ); return NULL; } void * thread6 ( void * args ) { sem_wait( &p46 ); sem_wait( &p56 ); for ( COUNT i = 0 ; i < maxLoop[6] ; i ++ ) { puts( "I am thread six." ); usleep(500000); } return NULL; } int main (void) { pthread_t threadid[7]; const int n = 10; srand( time(NULL) ); for ( COUNT i = 1 ; i < 7 ; i ++ ) maxLoop[i] = (rand() % n) + 1; if ( sem_init( &p12, 0, 0 ) == -1 ) { fprintf( stderr, "Error Initializing Semaphore\n\n"); return EXIT_FAILURE; } if ( sem_init( &p13, 0, 0 ) == -1 ) { fprintf( stderr, "Error Initializing Semaphore\n\n"); return EXIT_FAILURE; } if ( sem_init( &p24, 0, 0 ) == -1 ) { fprintf( stderr, "Error Initializing Semaphore\n\n"); return EXIT_FAILURE; } if ( sem_init( &p25, 0, 0 ) == -1 ) { fprintf( stderr, "Error Initializing Semaphore\n\n"); return EXIT_FAILURE; } if ( sem_init( &p35, 0, 0 ) == -1 ) { fprintf( stderr, "Error Initializing Semaphore\n\n"); return EXIT_FAILURE; } if ( sem_init( &p46, 0, 0 ) == -1 ) { fprintf( stderr, "Error Initializing Semaphore\n\n"); return EXIT_FAILURE; } if ( sem_init( &p56, 0, 0 ) == -1 ) { fprintf( stderr, "Error Initializing Semaphore\n\n"); return EXIT_FAILURE; } if ( pthread_create( &threadid[1], NULL, thread1, NULL ) ) { fprintf( stderr, "Error Creating Thread.\n\n" ); return EXIT_FAILURE; } if ( pthread_create( &threadid[2], NULL, thread2, NULL ) ) { fprintf( stderr, "Error Creating Thread.\n\n" ); return EXIT_FAILURE; } if ( pthread_create( &threadid[3], NULL, thread3, NULL ) ) { fprintf( stderr, "Error Creating Thread.\n\n" ); return EXIT_FAILURE; } if ( pthread_create( &threadid[4], NULL, thread4, NULL ) ) { fprintf( stderr, "Error Creating Thread.\n\n" ); return EXIT_FAILURE; } if ( pthread_create( &threadid[5], NULL, thread5, NULL ) ) { fprintf( stderr, "Error Creating Thread.\n\n" ); return EXIT_FAILURE; } if ( pthread_create( &threadid[6], NULL, thread6, NULL ) ) { fprintf( stderr, "Error Creating Thread.\n\n" ); return EXIT_FAILURE; } for ( COUNT i = 1 ; i < 7 ; i ++ ) { if ( pthread_join( threadid[i] , NULL ) ) { fprintf( stderr, "Error Joining Thread.\n\n" ); return EXIT_FAILURE; } } return EXIT_SUCCESS; }
今天突然想起此事,于是用C++ 11标准新引入的STL线程库重新实现一遍。
/* * thread_synchronization.cpp * * Copyright 2013 叶剑飞 * * 编译命令: * g++ thread_synchronization.cpp -o thread_synchronization -Wall -std=c++11 -pthread * */ #include <cstdio> #include <cstdlib> #include <ctime> #include <thread> #include <mutex> #include <chrono> using namespace std; typedef int COUNT; mutex p12, p13, p24, p25, p35, p46, p56; int maxLoop[7]; void thread1 ( ) { for ( COUNT i = 0 ; i < maxLoop[1] ; i ++ ) { puts( "I am thread one." ); this_thread::sleep_for(chrono::milliseconds(500)); } p12.unlock( ); p13.unlock( ); } void thread2 ( ) { p12.lock( ); for ( COUNT i = 0 ; i < maxLoop[2] ; i ++ ) { puts( "I am thread two." ); this_thread::sleep_for(chrono::milliseconds(500)); } p24.unlock( ); p25.unlock( ); } void thread3 ( ) { p13.lock( ); for ( COUNT i = 0 ; i < maxLoop[3] ; i ++ ) { puts( "I am thread three." ); this_thread::sleep_for(chrono::milliseconds(500)); } p35.unlock( ); } void thread4 ( ) { p24.lock( ); for ( COUNT i = 0 ; i < maxLoop[4] ; i ++ ) { puts( "I am thread four." ); this_thread::sleep_for(chrono::milliseconds(500)); } p46.unlock( ); } void thread5 ( ) { p25.lock( ); p35.lock( ); for ( COUNT i = 0 ; i < maxLoop[5] ; i ++ ) { puts( "I am thread five." ); this_thread::sleep_for(chrono::milliseconds(500)); } p56.unlock( ); } void thread6 ( ) { p46.lock( ); p56.lock( ); for ( COUNT i = 0 ; i < maxLoop[6] ; i ++ ) { puts( "I am thread six." ); this_thread::sleep_for(chrono::milliseconds(500)); } } bool LockAllMutex ( ) { try { p12.lock( ); p13.lock( ); p24.lock( ); p25.lock( ); p35.lock( ); p46.lock( ); p56.lock( ); } catch ( ... ) { return false; } return true; } bool CreateAllThread( thread * threadid ) { try { threadid[1] = thread( thread1 ); threadid[2] = thread( thread2 ); threadid[3] = thread( thread3 ); threadid[4] = thread( thread4 ); threadid[5] = thread( thread5 ); threadid[6] = thread( thread6 ); } catch( ... ) { return false; } return true; } int main (void) { thread threadid[7]; const int n = 10; srand( time(NULL) ); for ( COUNT i = 1 ; i < 7 ; i ++ ) maxLoop[i] = (rand() % n) + 1; if ( !LockAllMutex ( ) ) { fprintf( stderr, "Error Locking the Mutex \n\n"); return EXIT_FAILURE; } if ( !CreateAllThread( threadid ) ) { fprintf( stderr, "Error Creating Thread.\n\n" ); return EXIT_FAILURE; } for ( COUNT i = 1 ; i < 7 ; i ++ ) { try { threadid[i].join( ); } catch( ... ) { fprintf( stderr, "Error Joining Thread.\n\n" ); return EXIT_FAILURE; } } return EXIT_SUCCESS; }
发现C++ 11线程真心简单。