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

来源:互联网 发布:元数据如何保存 编辑:程序博客网 时间:2024/04/29 16:29
#include <pthread.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <assert.h>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 90000000int 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 <semaphore.h>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 <assert.h>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 <time.h>/* *  */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:90000010 sec mutex done 1:37:90000010 sec sem_for_mutex done 1:25:9000000010 sec only mutex done 1:14:9000000010 sec only sem done 1:50:9000000010 sec mix done 1:25:90000000



原创粉丝点击