线程A分为A1,A2两个步骤,A1执行完毕后通知线程B,线程B执行完毕后通知线程A,线程A接下来执行步骤A2

#include 
#include 
#include 
#include 
#include 


static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t waite_recv = PTHREAD_COND_INITIALIZER;
static pthread_cond_t waite_send = PTHREAD_COND_INITIALIZER;

static volatile int message = 0;
static volatile int sem_counts = 0;
static volatile int mut_counts = 0;

#define DO_COUNTS 90000000

int get_sem_counts(){
    return sem_counts;
}

int get_mut_counts(){
    return mut_counts;
}
void reset_mut_counts(){
    mut_counts = 0;
}

#define CHECK_ROUTE( x ) do{\
        int __ret__ = x;\
        if( 0 != __ret__ ){\
                printf("[%s:%d]:%d-%d(%s)\n",__FUNCTION__,__LINE__,__ret__,errno,strerror(errno));\
                return NULL;\
        }\
}while(0)


static void* recv_thread(void* arg) {
    int i = 0;
    for (;i < DO_COUNTS/100; ++i) {
         CHECK_ROUTE(pthread_mutex_lock(&mutex));
        /*
         * be care this wait may be excute after
         * broadcast or signal 
         * in that way U may be lost one condtion
         * at least even may be dead lock here
         * so we must introduce a var to test
         * whether ok.
         */
        for(; 0 == message;) 
        {
            CHECK_ROUTE(pthread_cond_wait(&waite_send, &mutex));
        }
        --message;
        CHECK_ROUTE(pthread_cond_signal(&waite_recv));
        CHECK_ROUTE(pthread_mutex_unlock(&mutex));
        ++mut_counts;
    }
    return NULL;
}

static void* send_thread(void* arg) {
    int i = 0;
    for (;i < DO_COUNTS/100; ++i) {
        CHECK_ROUTE(pthread_mutex_lock(&mutex));
        ++message;
        /**
         * be care this route may be no using when 
         * there're no any thread waite this conition
         * so must changed this usage
         */
        CHECK_ROUTE(pthread_cond_signal(&waite_send));
        CHECK_ROUTE(pthread_cond_wait(&waite_recv, &mutex));
        CHECK_ROUTE(pthread_mutex_unlock(&mutex));

    }
    return NULL;
}

/*
 * this test could work but ....
 */
void* test_mutex_for_semphone(){
    pthread_t recver,sender;
    int i,k;
    void *r = &i,*s = &k;
    message = 0;
    CHECK_ROUTE(pthread_mutex_init(&mutex,NULL));
    CHECK_ROUTE(pthread_cond_init(&waite_recv,NULL));
    CHECK_ROUTE(pthread_cond_init(&waite_send,NULL));
    CHECK_ROUTE(pthread_create(&recver,NULL,recv_thread,NULL));
    CHECK_ROUTE(pthread_create(&sender,NULL,send_thread,NULL));
    CHECK_ROUTE(pthread_join(recver,&r));
    CHECK_ROUTE(pthread_join(sender,&s));
    CHECK_ROUTE(pthread_cond_destroy(&waite_recv));
    CHECK_ROUTE(pthread_cond_destroy(&waite_send));
    CHECK_ROUTE(pthread_mutex_destroy(&mutex));
    assert(message == 0);
}

#include 

static sem_t send_sem;
static sem_t recv_sem;
void*  sem_send_thread(void* arg){
    int i = 0;
    for(; i < DO_COUNTS/100; ++i){
        ++message;
        CHECK_ROUTE(sem_post(&send_sem));
        CHECK_ROUTE(sem_wait(&recv_sem));
    }
    return NULL;
}

void* sem_recv_thread(){
    int i = 0;    
    for(; i < DO_COUNTS/100; ++i){
        CHECK_ROUTE(sem_wait(&send_sem));
        --message;
        ++mut_counts;
        CHECK_ROUTE(sem_post(&recv_sem));
        ++sem_counts;
    }
    return NULL;    
}



void* test_emphone(){
    pthread_t recver,sender;
    int i,k;
    void *r = &i,*s = &k;
    message = 0;
    CHECK_ROUTE(sem_init(&send_sem,0,0));
    CHECK_ROUTE(sem_init(&recv_sem,0,0));
    CHECK_ROUTE(pthread_create(&recver,NULL,sem_recv_thread,NULL));
    CHECK_ROUTE(pthread_create(&sender,NULL,sem_send_thread,NULL));
    CHECK_ROUTE(pthread_join(recver,&r));
    CHECK_ROUTE(pthread_join(sender,&s));
    CHECK_ROUTE(sem_destroy(&send_sem));
    CHECK_ROUTE(sem_destroy(&recv_sem));
    assert(message == 0);
}


/*
 * 
 * using sem as a mutex to metex var operation
 * no any other process
 * 
 */

static sem_t sem_mutex;

static void* sem_mutex_recv_thread(void* arg){
    int i = 0;
    
    for(; i < DO_COUNTS ; ++i){
        CHECK_ROUTE(sem_wait(&sem_mutex));
        --message;
        ++mut_counts;
         CHECK_ROUTE(sem_post(&sem_mutex));
    }
}

static void* sem_mutex_send_thread(void* arg){
    int i = 0;
    for(; i < DO_COUNTS ; ++i){
        CHECK_ROUTE(sem_wait(&sem_mutex));
        ++message;
        CHECK_ROUTE(sem_post(&sem_mutex));
    }
}


void* test_sem_for_mutex(){
    pthread_t recver,sender;
    int i,k;
    void *r = &i,*s = &k;
    message = 0;
    CHECK_ROUTE(sem_init(&sem_mutex,0,1));
    CHECK_ROUTE(pthread_create(&recver,NULL,sem_mutex_recv_thread,NULL));
    CHECK_ROUTE(pthread_create(&sender,NULL,sem_mutex_send_thread,NULL));
    CHECK_ROUTE(pthread_join(recver,&r));
    CHECK_ROUTE(pthread_join(sender,&s));
    CHECK_ROUTE(sem_destroy(&sem_mutex));
    assert(message == 0);
}

/*
 * 
 * only test for mutex var operation
 * no any other process
 * 
 */

static void* mutex_recv_thread(void* arg){
    int i = 0;
    
    for(; i < DO_COUNTS ; ++i){
        CHECK_ROUTE(pthread_mutex_lock(&mutex));
        --message;
        ++mut_counts;
        CHECK_ROUTE(pthread_mutex_unlock(&mutex));
    }
    
}

static void* mutex_send_thread(void* arg){
    int i = 0;
    for(; i < DO_COUNTS ; ++i){
        CHECK_ROUTE(pthread_mutex_lock(&mutex));
        ++message;
        CHECK_ROUTE(pthread_mutex_unlock(&mutex));
    }
}

void* test_mutex(){
    pthread_t recver,sender;
    int i,k;
    void *r = &i,*s = &k;
    message = 0;
    CHECK_ROUTE(pthread_mutex_init(&mutex,NULL));
    CHECK_ROUTE(pthread_create(&recver,NULL,mutex_recv_thread,NULL));
    CHECK_ROUTE(pthread_create(&sender,NULL,mutex_send_thread,NULL));
    CHECK_ROUTE(pthread_join(recver,&r));
    CHECK_ROUTE(pthread_join(sender,&s));
    CHECK_ROUTE(pthread_mutex_destroy(&mutex));
    assert(message == 0);
}

static sem_t sem_sig;

static void* sem_sig_send(void* arg) {
    int i = 0;
    for (; i < DO_COUNTS; ++i) {        
        /*
         *  ++ operation is not automic operation  
         *  so after following opeation the message
         *  value not make sure
         *  in this case 
         */
        ++message;++mut_counts;
        CHECK_ROUTE(sem_post(&sem_sig));
    }
    return NULL;
}
static void* sem_sig_recv(void* arg){
    int i = 0,k = 0;
    for (; i < DO_COUNTS; ++i) {
        CHECK_ROUTE(sem_wait(&sem_sig));  
        /*
         * this operation not safe maybe dirty read and wirte
         */
        --message;
    }
}

void* test_sem_for_sig(){
    pthread_t recver,sender;
    int i,k;
    void *r = &i,*s = &k;
    CHECK_ROUTE(sem_init(&sem_sig,0,0));
    message = 0;
    CHECK_ROUTE(pthread_create(&recver,NULL,sem_sig_send,NULL));
    CHECK_ROUTE(pthread_create(&sender,NULL,sem_sig_recv,NULL));
    CHECK_ROUTE(pthread_join(recver,&r));
    CHECK_ROUTE(pthread_join(sender,&s));
    CHECK_ROUTE(sem_destroy(&sem_sig));
}

static pthread_mutex_t guard;
static sem_t wait_object;


static void* mix_send(void* arg) {
    int i = 0;
    for (; i < DO_COUNTS; ++i) {        
        pthread_mutex_lock(&guard);
        ++message;++mut_counts;
        pthread_mutex_unlock(&guard);
        CHECK_ROUTE(sem_post(&wait_object));
    }
    return NULL;
}
static void* mix_recv(void* arg){
    int i = 0,k = 0;
    for (; i < DO_COUNTS; ++i) {
        CHECK_ROUTE(sem_wait(&wait_object));  
        pthread_mutex_lock(&guard);
        --message;
        pthread_mutex_unlock(&guard);
    }
    return NULL;
}
#include 
void* test_mix(){
    pthread_t recver,sender;
    int i,k;
    void *r = &i,*s = &k;
    CHECK_ROUTE(sem_init(&wait_object,0,0));
    CHECK_ROUTE(pthread_mutex_init(&guard,NULL));
    message = 0;
    CHECK_ROUTE(pthread_create(&recver,NULL,mix_send,NULL));
    CHECK_ROUTE(pthread_create(&sender,NULL,mix_recv,NULL));
    CHECK_ROUTE(pthread_join(recver,&r));
    CHECK_ROUTE(pthread_join(sender,&s));
    CHECK_ROUTE(sem_destroy(&wait_object));
    CHECK_ROUTE(pthread_mutex_unlock(&guard));
    assert(message == 0);
}
#include 
/*
 * 
 */
void find_id_number(const char* tail_xx);
void* test_mutex_for_semphone();
void* test_emphone();
void* test_mutex();
void* test_sem_for_mutex();
void* test_sem_for_sig();
void* test_sem_mix();
int get_sem_counts();
int get_mut_counts();
void reset_mut_counts();

static void test_time(){
    time_t now = time(NULL);
    int i = 0,interval = time(NULL) - now;
    for (; interval < 10; ++i) {
        test_emphone();
        interval = time(NULL) - now;
    }
    printf("10 sec sem done %d:%d:%d\n", i,interval,get_sem_counts());
    reset_mut_counts();
    now = time(NULL);
    interval = time(NULL) - now;
    for (i = 0; interval < 10; ++i) {
        test_mutex_for_semphone();
        interval = time(NULL) - now;
    }
    printf("10 sec mutex done %d:%d:%d\n", i,interval,get_mut_counts());    
    reset_mut_counts();
    now = time(NULL);
    interval = time(NULL) - now;
    for (i = 0; interval < 10; ++i) {
        test_sem_for_mutex();
        interval = time(NULL) - now;
    }
    printf("10 sec sem_for_mutex done %d:%d:%d\n", i,interval,get_mut_counts());        
    reset_mut_counts();
    now = time(NULL);
    interval = time(NULL) - now;
    for (i = 0; interval < 10; ++i) {
        test_mutex();
        interval = time(NULL) - now;
    }
    printf("10 sec only mutex done %d:%d:%d\n", i,interval,get_mut_counts());        
    reset_mut_counts();
    now = time(NULL);
    interval = time(NULL) - now;
    for (i = 0; interval < 10; ++i) {
        test_sem_for_sig();
        interval = time(NULL) - now;
    }
    printf("10 sec only sem done %d:%d:%d\n", i,interval,get_mut_counts());        
    reset_mut_counts();
    now = time(NULL);
    interval = time(NULL) - now;
    for (i = 0; interval < 10; ++i) {
        test_mix();
        interval = time(NULL) - now;
    }
    printf("10 sec mix done %d:%d:%d\n", i,interval,get_mut_counts());            
}

int main(int argc, char** argv) {
    test_time();
    return (EXIT_SUCCESS);
}
10 sec sem done 1:25:900000
10 sec mutex done 1:37:900000
10 sec sem_for_mutex done 1:25:90000000
10 sec only mutex done 1:14:90000000
10 sec only sem done 1:50:90000000
10 sec mix done 1:25:90000000



你可能感兴趣的:(互联网)