现在的位置: 首页 > 综合 > 正文

Linux多线程使用实例

2018年03月16日 ⁄ 综合 ⁄ 共 2832字 ⁄ 字号 评论关闭

以前在Windows编写过很多多线程的应用程序,对于多线程的编写原理比较熟悉,但是在Linux很少真正用多线程编写过应用,Linux下多线程库pthread使用与Windows上多线程使用有不少差别,个人感觉Windows设计的线程库比较人性化,对使用者来说很容易掌握,但是在灵活性方面不如Linux。
下面就是一个使用pthread库编写的一个简单多线程demo,实现同时启动两个线程的功能,代码如下:

#include <stdio.h>
#include <pthread.h>

int count=0 ;
pthread_mutex_t mutex ;
pthread_mutex_t wait_all_start;
pthread_cond_t condition ;

pthread_t thrd1 ;
pthread_t thrd2 ;
bool all_threads_start=false ;
bool b_thrd1_ready=false ;
bool b_thrd2_ready=false ;
void *thread_fun1(void *param)
{
    b_thrd1_ready=true ;

    /*注意信号等待的用法,需要使用一个与被保护变量相同的互斥量*/
    pthread_mutex_lock(&wait_all_start) ;
    while(!all_threads_start){//防止被干扰信号唤醒
        pthread_cond_wait(&condition,&wait_all_start) ;
    }
    pthread_mutex_unlock(&wait_all_start) ;

    int a=0 ;
    while(a++!=10)
    {
        pthread_mutex_lock(&mutex) ;
        printf("%s:count=%d\n",__func__,count++) ;
        pthread_mutex_unlock(&mutex) ;
        Sleep(100);
    }
}
void *thread_fun2(void *param)
{
    b_thrd2_ready=true ;

    pthread_mutex_lock(&wait_all_start) ;
    while(!all_threads_start){
        pthread_cond_wait(&condition,&wait_all_start) ;
    }
    pthread_mutex_unlock(&wait_all_start) ;

    int a=0 ;
    while(a++!=10)
    {
        pthread_mutex_lock(&mutex) ;
        printf("%s:count=%d\n",__func__,count++) ;
        pthread_mutex_unlock(&mutex) ;
        Sleep(100) ;
    }
}
int main()
{
    pthread_mutex_init(&mutex,NULL) ;
    pthread_mutex_init(&wait_all_start ,NULL) ;
    pthread_cond_init(&condition,NULL) ;


    b_thrd1_ready=false ;
    b_thrd2_ready=false ;
    all_threads_start=false ;

    if(pthread_create(&thrd1,NULL,thread_fun1,NULL)!=0){
        printf("Create Thread 1 Failed!\n") ;
        return -1 ;
    }
    if(pthread_create(&thrd2,NULL,thread_fun2,NULL)!=0){
        printf("Create Thread 2 Failed!\n") ;
        return -1 ;
    }
    printf("Create two thread done.....\n") ;

    while(true){/*等待需要唤醒的条件,防止在等待线程等待之前,就执行下去,注意下面发送信号的用法,使用if*/
        pthread_mutex_lock(&wait_all_start) ;
        printf("main thread......\n") ;
        if(b_thrd1_ready&&b_thrd2_ready){//等待,确保两个线程都进入等待状态
            printf("all threads ready......\n") ;
            all_threads_start=true ;
            pthread_cond_broadcast(&condition);
            //pthread_cond_signal(&condition) ;
            pthread_mutex_unlock(&wait_all_start) ;//注意这里别忘记了
            break ;
        }
        Sleep(10) ;
        pthread_mutex_unlock(&wait_all_start) ;
    }
    pthread_join(thrd1,NULL) ;
    pthread_join(thrd2,NULL) ;
    printf("\ncount=%d\n",count) ;
    return 0 ;

}

在使用pthread线程库时,需要注意一下几点:
1、互斥锁pthread_mutex_t只能本线程解锁,即如果在本线程中使用pthread_mutex_lock,就必须在本线程中使用pthread_mutex_unlock解锁;这也是在线程同步中与信号量的区别,信号量可以在不同的线程中加锁和解锁
2、使用条件变量pthread_cond_t,在调用pthread_cond_wait的时候需要传入一个互斥锁,当进入这个pthread_cond_wait函数内部时,会对这个这个互斥锁执行解锁操作,等待其他线程修改等待的条件,当条件满足被其他线程唤醒时,这个函数会执行加锁操作。
3、pthread_cont_wait这个函数有可能被其他干扰唤醒;比如说pthread_cond_signal有可能唤醒多个线程;
4、pthread_cond_signal函数在执行唤醒操作是一瞬间的,此时不管有没有线程在等待,这个信号都会消失,如果有线程等待就会唤醒该线程,如果此时没有线程进入等待状态,在此后有线程进入等待状态,这个信号也将无效;
为了避免上面3、4点,一般使用信号量等待和释放的模式是这样的:
等待线程使用模式:

pthread_mutex_lock(&xxxmutex) ;
while(b_xxx_flag)
        pthread_cond_wait(&xxxcond,&xxxmutex);
pthread_mutex_unlock(&xxxmutex)

信号发送线程使用模式:

while(true){
       pthread_mutex_lock(&xxxmutex) ;
       if(b_ready){
             b_xxx_flag=true ;
             pthread_cond_signal(&xxxcond) ;
            pthread_mutex_unlock(&xxxmutex) ;
            break ;
      }
      pthread_mutex_unlock(&xxxmutex) ;
}

抱歉!评论已关闭.