linux线程等待_linux 如何设置等待线程超时 - CSDN
精华内容
参与话题
  • linux下线程等待

    2013-10-29 23:10:12
    #include int pthread_join(pthread_t tid,void **rval_ptr) ...tid: 等待退出的线程id rval_ptr: 线程退出的返回值的指针 实例分析: #include #include #include void *thread(void *str) {  int
    #include <pthread.h>
    int pthread_join(pthread_t tid,void **rval_ptr)

    功能:阻塞调用线程,直到指定的线程终止。

    tid: 等待退出的线程id

    rval_ptr: 线程退出的返回值的指针

    实例分析:

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


    void *thread(void *str)
    {
        int i;
        for (i = 0; i < 10; ++i)
        {
            sleep(2);
            printf( "This in the thread : %d\n" , i );
        }
        return NULL;
    }


    int main()
    {
        pthread_t pth;
        int i;
        int ret = pthread_create(&pth, NULL, thread, (void *)(i));
        
       pthread_join(pth, NULL);
        printf("123\n");
        for (i = 0; i < 10; ++i)
        {
            sleep(1);
            printf( "This in the main : %d\n" , i );
        }
        
        return 0;
    }



    若没有pthread_join

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


    void *thread(void *str)
    {
        int i;
        for (i = 0; i < 10; ++i)
        {
            sleep(2);
            printf( "This in the thread : %d\n" , i );
        }
        return NULL;
    }


    int main()
    {
        pthread_t pth;
        int i;
        int ret = pthread_create(&pth, NULL, thread, (void *)(i));
        
       // pthread_join(pth, NULL);
        printf("123\n");
        for (i = 0; i < 10; ++i)
        {
            sleep(1);
            printf( "This in the main : %d\n" , i );
        }
        
        return 0;
    }



    展开全文
  • Linux 线程等待

    2020-04-05 09:44:53
    Linux 线程等待 转载自https://www.xuebuyuan.com/2201259.html 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出...

    Linux 线程等待

    转载自https://www.xuebuyuan.com/2201259.html
    条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。

    一 pthread_cond_wait定义:

    函数原型:int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)

    参数: cond 条件变量 mutex 互斥锁
    第一个参数cond是指向一个条件变量的指针。第二个参数mutex则是对相关的互斥锁的指针。

    二 pthread_cond_wait示例理解

    pthread_cond_wait的机制比较难里理解,是条件变量中重要的成分。条件变量用于线程间同步,那么pthread_cond_wait必须和互斥锁同时作用在一个线程里,它同时起到对资源的加锁和解锁,看下面的示例:

    程序创建了2个新线程使他们同步运行,实现进程t_b打印9以内3的倍数,t_a打印其他的数,程序开始线程t_b不满足条件等待,线程t_a运行使a循环加1并打印。直到i为3的倍数时,线程t_a发送信号通知进程t_b,这时t_b满足条件,打印i值。

    #include<pthread.h>
    #include<unistd.h>
    #include<stdio.h>
     #include<stdlib.h>
    
     pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
    pthread_cond_t  cond = PTHREAD_COND_INITIALIZER;//init cond
    
     void *thread1(void*);
    void *thread2(void*);
    
     int i = 1; //global
    
    int main(void){
         pthread_t t_a;
         pthread_t t_b;//two thread
    
         pthread_create(&t_a,NULL,thread2,(void*)NULL);
         pthread_create(&t_b,NULL,thread1,(void*)NULL);//Create thread
     
        pthread_join(t_b,NULL);//wait a_b thread end
         pthread_mutex_destroy(&mutex);
         pthread_cond_destroy(&cond);
         exit(0);
     }
     
     void *thread1(void *junk){
         for(i = 1;i<= 9; i++){
             pthread_mutex_lock(&mutex); //互斥锁
             printf("call thread1 \n");
            if(i%3 == 0)
                 pthread_cond_signal(&cond); //send sianal to t_b
             else
                 printf("thread1: %d\n",i);
             pthread_mutex_unlock(&mutex);
             sleep(1);
         }
     }
    
     void *thread2(void*junk){
         while(i < 9)
         {
            pthread_mutex_lock(&mutex);
             printf("call thread2 \n");
           if(i%3 != 0)
                pthread_cond_wait(&cond,&mutex); //wait
             printf("thread2: %d\n",i);
             pthread_mutex_unlock(&mutex);
             sleep(1);
         }
     }
    

    输出:
    call thread2
    call thread1
    thread1: 1
    call thread1
    thread1: 2
    call thread1
    thread2: 3
    call thread1
    thread1: 4
    call thread2
    call thread1
    thread1: 5
    call thread1
    thread2: 6
    call thread1
    thread1: 7
    call thread2
    call thread1
    thread1: 8
    call thread1
    thread2: 9

    示例的解释:
    call thread2:是线程2即t_b首先上锁,即 pthread_mutex_lock(&mutex);锁住了mutex使得此进程执行线程2中的临界区的代码,当执行到45行:if(i%3 != 0),此时i=1,满足此条件,则执行46行: pthread_cond_wait(&cond,&mutex); 这句是关键,pthread_cond_wait(&cond,&mutex)操作有两步,是原子操作:第一
    解锁,先解除之前的pthread_mutex_lock锁定的mutex;第二 挂起,阻塞并在等待对列里休眠,即线程2挂起,直到再次被唤醒,唤醒的条件是由pthread_cond_signal(&cond);发出的cond信号来唤醒。

    call thread1:由于pthread_cond_wait已经对线程2解锁,此时另外的线程只有线程1,那么线程1对mutex上锁,若这时有多个线程,那么线程间上锁的顺序和操作系统有关。

    thread1: 1:线程1上锁后执行临界区的代码,当执行到if(i%3 == 0)此时i=1,不满足条件,则pthread_cond_signal(&cond);不被执行,那么线程2仍处于挂起状态,输出thread1: 1后线程1由pthread_mutex_unlock(&mutex);解锁。

    thread1: 2:这时此进程中只有2个线程,线程2处于挂起状态,那么只有线程1,则线程1又对mutex上锁,此时同样执行临界区的代码,而且i=2,不满足条件,pthread_cond_signal(&cond);不被执行,那么线程2仍处于挂起状态,输出thread1: 1后线程1由pthread_mutex_unlock(&mutex);解锁。

    call thread1:同样由线程1上锁,但此时i=3,满足条件pthread_cond_signal(&cond)被执行,那么pthread_cond_signal(&cond)会发出信号,来唤醒处于挂起的线程2。pthread_cond_signal同样由两个原子操作:1,解锁;2,发送信号;解锁即对线程1解锁,解除对mutex的上锁。发送信号,即给等待signal挂起的线程2发送信号,唤醒挂起的线程2。(错误)pthread_cond_signal只会发送信息,让pthread_cond_wait线程从cond_wait队列转移至mutex_wait队列。

    thread2: 3:由于pthread_cond_signal唤醒了线程2,即i=3满足条件,pthread_cond_wait(&cond,&mutex);被执行,那么pthread_cond_wait(&cond,&mutex)此时也有一步操作:上锁;即对线程2上锁,此时的pthread_cond_wait(&cond,&mutex)的操作相当与pthread_mutex_lock(&mutex);那么线程2继续执行上锁后的临界区的代码,并由pthread_mutex_unlock(&mutex);对线程2进行解锁。

    剩下的输出原理和上面解释的一样。

    纵观pthread_cond_wait,它的理解不可之把它看作一个简单的wait函数,它里面应该是一族函数,不同的函数在不同的条件下执行,理解pthread_cond_wait的机制可以很好的学习条件变量。

    展开全文
  • Linux线程部分总结分为两部分:(1)线程的使用 ,(2)线程的同步与互斥。 第一部分线程的使用主要介绍,线程的概念,创建线程,线程退出,以及线程的终止与分离。第二部分主要介绍在多线程环境下,使用同步与互斥...

    学习环境 :  Centos6.5 Linux 内核 2.6

    Linux线程部分总结分为两部分:(1)线程的使用 ,(2)线程的同步与互斥。

    第一部分线程的使用主要介绍,线程的概念,创建线程,线程退出,以及线程的终止与分离。

    第二部分主要介绍在多线程环境下,使用同步与互斥保护共享资源,有互斥锁,条件变量,信号量,以及读写锁。

    第一部分开始


    初识线程

    线程:也称轻量级进程(Lightweight Process , LWP),是程序执行流的最小单元。而多线程就是指,在一个进程中有多个执行流,在同时执行。

    为什么需要多线程呢?

    在客户端,我们需要界面和用户交互动作,此时就可以在后台线程去处理交互逻辑。比如下载一个文件利用一个线程,而同时还可以用一个线程响应用户的其他操作。

    在服务端,如http服务器,会同时有多个请求需要处理,此时利用多线程可以大大提高请求的处理效率。

    线程与进程的区别:

    进程是资源分配的基本单位,而线程是调度的基本单元。操作系统中每一个执行的进程,都有它自己的地址空间,而同一进程中可以有多个线程,也就是多个执行流在同时执行。这里的同时,如果是单核处理器,则此时并不是真正意义上的同时,由于处理器运行速度很快,给每个执行流分配了时间片,在单核处理器中微观上还是顺序执行,而在多核处理器中,就是真正意义上的并行。由于同一进程的多个线程共享同一地址空间,因此线程之间有互相共享的资源,也有彼此独占的资源。

    线程之间共享的资源主要有

    • 地址空间
    • 数据段和代码段
    • 全局变量
    • 文件描述符表
    • 信号处理方式(忽略或者有自定义动作)
    • 用户ID和组ID
    • 当前工作目录

    每个线程各有一份的资源主要有

    • 线程ID
    • 上下文(寄存器,程序计数器,栈指针)
    • 栈空间
    • 状态字
    • 信号屏蔽字
    • 调度优先级

    进程与线程的区别归纳如下几点:

    1. 地址空间:进程间相互独立,每个进程都有自己独立的地址空间,同一进程的各线程间共享地址空间。某个进程内的线程在其他进程内不可见。
    2. 通信关系:进程间通信有管道,消息队列,共享内存,信号量。线程间通信可以直接读写全局变量来进行通信。不管是进程还是线程,通信时可能出现数据不一致的情况,需要用同步互斥机制来保证数据的一致性。
    3. 切换和调度:由于进程间独占数据段代码段等信息,所以切换进程的时候,需要把进程间独占的资源切换去,把要执行的进程资源换进来,而线程是进程的子集,共享大部分资源,切换时只需要保存上下文相关信息就好,所以线程切换的开销比进程切换的开销小。

    线程的三种状态

    线程主要有三种状态分别是就绪、阻塞、运行。

    就绪:线程具备运行的所有条件,逻辑上已可以运行,在等待处理机。

    阻塞:指线程在等待某一时间的发生,如I/O操作。

    运行:占有处理器正在运行。

    :关于进程与线程之间阻塞状态的关系,在文末做了个实验。

    线程的控制

    主要学习如何创建一个线程,线程有哪些终止方式,以及怎么获取一个线程的运行结果,判断线程是否异常退出,线程生命结束时有没有”遗言“。

    这里学习的线程库函数由POSIX标准定义的,称为POSIX thread 或者 pthread。在Linux中函数位于libpthread共享库中,在gcc编译或者Makefile中记得要加上 -lpthread选项,用来指定要链接的库。函数在执行错误时的错误信息将作为返回值返回,并不修改全局变量errno,也就无法通过 perror() 打印错误信息。

    创建线程

    #include <pthread.h>
    
    int pthread_create(pthread_t *thread, 
                       const pthread_attr_t *attr, 
                       void *(*start_routine)(void *), 
                       void *arg);
    

    描述:创建一个线程,用第一个参数线程标识符,第二个参数设置线程属性,第三个参数指定线程函数运行的起始地址(函数指针),第四个参数是运行函数的参数。

    实例:下面的代码创建了两个线程,并分别在线程中调用pthread_self()打印各自的线程ID,以及调用 getpid() 打印进程ID,为了对比也在创建线程的Main执行流中打印线程ID,和进程ID。

    #include <stdio.h>
    #include <pthread.h>    // pthread_create()
    #include <unistd.h>     // sleep()
    #include <sys/types.h>  // getpid()
    
    // 打印每个线程的ID, 和进行ID
    
    void * run_1(void *arg)  // 线程1 执行代码
    {
        sleep(1);
        printf(" thread 1 tid is  %u,  pid is %u \n", pthread_self(), getpid()); 
    }
    
    void * run_2(void *arg)  // 线程2 执行代码
    {
    
        sleep(1);
        printf(" thread 2 tid is  %u,  pid is %u \n", pthread_self(), getpid());
    }
    
    int main()
    {
        pthread_t tid1, tid2;
    
        pthread_create(&tid1, NULL, run_1, NULL ); // 创建线程1
        pthread_create(&tid2, NULL, run_2, NULL ); // 创建线程2
    
        sleep(2);
        printf("I am main tid is  %u,  pid is %u \n", pthread_self(), getpid());
        return 0;
    }
    

    创建线程

    从上图执行结果以及对代码的分析可以得出:

    1).线程1 和线程2 的进程ID一样,可以说明同一个进程可以拥有多个线程,即多个执行流。

    2 ) .我们发现在main 执行流中打印线程ID ,与创建的线程差异并不大,也就是说main 执行流也是一个线程。也可以这样理解:在Linux中,一个进程默认有一个线程。单线程也就是单进程。

    3 ).在代码中之所以要在main 的执行流中sleep(2),是因为线程执行顺序与操作系统的调度算法有关系,为了保证创建的线程1 和线程2 先执行,故在 main的打印之前加上sleep(2)。

    4 ).在线程1 和线程2 的执行代码中都是一开始就sleep(1),而我们在main中创建线程的时候却是先创建的线程1,但是打印结果却是,线程2 先打印,这进一步证实了 3) 中所说,同一个进程中哪一个线程先执行与操作系统调度有关。

    5 ). 有一点需要强调,当main 结束的时候,运行到return,或者调用exit(),所有线程也会随之结束,下面的小程序证明这点。

    #include <stdio.h>
    #include <unistd.h> // sleep()
    #include <pthread.h>
    #include <stdlib.h> // exit()
    
    void *run( void * arg)
    {
        while(1)
        {
            printf("I am still alive ... \n");
            sleep(1);
        }
    }
    
    int main()
    {
        pthread_t tid1;
        pthread_create(&tid1, NULL, run, NULL);
    
        sleep(2);
        printf(" The main thread ends and all threads end.\n");
        exit(0); // main thread quit
    
        return 0;
    }
    

    执行结果:新线程每隔1秒打印一次,主线程在2秒后exit,新线程也随之结束。
    主线程退出exit别的线程也会退出

    终止线程

    如果需要只终止某个线程而不是整个进程都终止,有三种方法。

    1). 从线程函数return,对主线程不使用,在main函数中return 相当于exit。

    #include <stdio.h>
    #include <unistd.h>
    #include <pthread.h>
    
    
    // 终止线程 方法1
    
    void * run(void * arg)
    {
        printf("I am still alive, after a second I will quit.\n");
        sleep(1);
    
        return NULL;
    
        printf("Never output.\n");
    }
    
    int main()
    {
        pthread_t tid1;
        pthread_create(&tid1, NULL, run, NULL);
    
        sleep(2); // 确保主线程最后退出 
        printf("The thread quit, I should quit.\n");
        return 0;
    }
    

    线程退出方式1

    2 ). 一个线程可以调用pthread_cancel() 终止同一进程中的另一个线程。比较复杂,暂不分析。

    3 ).线程可以调用 pthread_exit() 终止自己。

    #include <stdio.h>
    #include <unistd.h>
    #include <pthread.h>
    
    void * run(void *arg)
    {
        printf("1 .. \n");
        printf("2 .. \n");
        sleep(1);
        printf("3 .. \n");
        printf("4 .. \n");
        pthread_exit(NULL);
        printf("never output .\n");
    }
    
    int main()
    {
        pthread_t tid1; 
        pthread_create(&tid1, NULL, run, NULL);
    
        sleep(3);
        printf("thread quit, I should quit.\n");
        return 0;
    }
    

    线程退出方法3

    等待线程

    说说我理解的为什么需要线程等待,有时候需要让一个线程去执行一段代码,我们需要知道它是否帮我们完成了指定的要求,或者异常终止,这时候我们就需要获取线程运行结果,线程退出可以通过返回值带出或者通过pthread_exit()参数带出,拿到它的“遗言”。线程等待也有回收资源的用处,如果一个线程结束运行但没有被等待,那么它类似于僵尸进程,占用的资源在进程结束前都不会被回收,所以当一个线程运行完成后,我们应该等待回收资源。

    我们可以注意到在上面的例子中,线程退出返回值和pthread_exit()的参数都是NULL,说明我们根本不关心线程的”死活“。

    还有一个用处,在上面的例子中,我们都是在主线程中sleep()函数来防止新创建的线程还未结束,整个进程就结束,而现在我们可以用线程等待函数来达到这个目的。

    #include <pthread.h>
    
    int pthread_join(pthread_t thread, void ** retval);

    描述:调用该函数的线程将挂起等待,直到id为thread的线程终止。thread线程以不同的方法终止,通过pthread_join() 得到的终止状态是不同的,主要有如下几种:

    • thread线程通过return 返回, retval 所指向的单元里存放的是 thread线程函数的返回值。

    • thread线程是被的线程调用pthread_cancel() 异常终止掉,retval 所指向的单元存放的是常数PTHREAD_CANCELED.

    • 如果thread线程调用pthread_exit() 终止的,retval 所指向的单元存放的是传给pthread_exit的参数。

    下面来举个栗子,拿到线程的”遗言“:

    #include <stdio.h>
    #include <pthread.h>
    #include <unistd.h>
    
    void* run_1(void *arg)
    {
        printf(" I am thread 1 \n");
        return (void*)1; 
    }
    
    void* run_2(void *arg)
    {
        printf(" I am thread 2 \n");
    
        pthread_exit((void*)2);
    }
    
    
    int main()
    {
        pthread_t tid1, tid2;
        pthread_create(&tid1, NULL, run_1, NULL);
        pthread_create(&tid2, NULL, run_2, NULL);
    
        void* retval_1;
        void* retval_2;
        pthread_join(tid1, &retval_1);
        pthread_join(tid2, &retval_2);
    
        printf(" thread 1 retval is  %u \n", (int*)retval_1);
        printf(" thread 2 retval is  %u \n", (int*)retval_2);
    
        return 0;
    }
    

    执行结果,成功得到线程的”遗言“:

    线程等待

    注意:在上面的例子中,我们带出的是整型值,如果需要带出别的数据类型,则需要使用全局变量或者malloc动态分配的空间,不能带出线程执行函数内的变量,因为执行结束后,栈里的数据变成垃圾数据。

    线程分离

    无论何时,一个线程是可结合(joinable )的或者是分离(detached)的。

    当线程属于可结合时,它能够被其他线程join或者cancel回收资源。相反一个已经处于分离的线程是不能被join或cancel,资源会在终止时自动释放。

    创建一个线程,默认是可结合的,为了防止资源的泄露,我们可以显示的调用pthread_join() 回收资源。对一个处于可结合的线程调用pthread_join()后,可以将线程置于分离状态。不能对同一个线程调用两个join,对一个已经分离的线程调用join会返回错误号。

    其实在上面的例子中,已经有过通过join将一个线程分离,但是当在一个线程中通过调用pthread_join()来回收资源时,调用者就会被阻塞,如果需要回收的线程数目过多时,效率就大大下降。比如在一个Web 服务器中, 主线程为每一个请求创建一个线程去响应动作,我们并不希望主线程也为了回收资源而被阻塞,因为可能在阻塞的同时有新的请求,我们可以再使用下面的方法,让线程办完事情后自动回收资源。

    1 ). 在子线程中调用pthread_detach( pthread_self() )
    2 ).在主线程中调用pthread_detach( tid )

    可以将线程状态设为分离。运行结束后会自动释放所有资源。

    #include <stdio.h>
    #include <pthread.h>
    
    
    void* run(void * arg)
    {
        pthread_detach( pthread_self());
        printf("I will detach .. \n");
        return NULL;
    }
    
    int main()
    {
        pthread_t tid1;
        pthread_create(&tid1, NULL, run, NULL);
    
        sleep(1); // 因为主线程不会挂起等待,为了保证子线程先执行完分离,让主线程先等待1s
        int ret = 0;
        ret =  pthread_join(tid1, NULL);
        if( ret == 0)
        {
            printf(" join sucess. \n");
        }
        else
        {
            printf(" join failed. \n");
        }
        return 0;
    }
    

    执行结果:

    线程分离


    补文中提到的实验

    说明:之所有会有这个实验,是因为之前一直对进程阻塞时,线程是什么状态不是很清楚,以及线程阻塞会对进程和别的线程有什么影响。因此本次基于Linux中的轻量级线程做出实验,实验结果不一定对所有平台都有效。

    实验环境:centos 6.5 Linux 2.6

    实验内容:

    1). 阻塞一个线程,看其他线程是否也会阻塞,如果其他线程也阻塞,说明线程阻塞会导致整个进程阻塞。若其他线程未阻塞,则说明线程间状态独立。

    #include <stdio.h>
    #include <pthread.h>
    
    void *run_1(void *arg)  // 线程1 每隔1s 打印一条
    {
        while(1)
        {
            sleep(1);
            printf(" I am thread 1, tid is %u , runing ...\n", pthread_self());
        }
    }
    
    void *run_2(void *arg)  // 线程2 每隔1s 打印一条
    {
        while(1)
        {
            sleep(1);
            printf(" I am thread 2, tid is %u , runing ... \n", pthread_self());
        }
    }
    
    void *run_3(void *arg)  // 线程3  等待输入 ,输入完毕后打印
    {
        int input = 0;
        scanf("%d", &input);
        printf("iuput data id %d \n", input);
    }
    
    int main()   
    {
        pthread_t tid1, tid2, tid3;
    
        pthread_create(&tid1, NULL, run_1, NULL);
        pthread_create(&tid2, NULL, run_2, NULL);
        pthread_create(&tid3, NULL, run_3, NULL);
    
        pthread_join(tid1, NULL);    // 主线程 等待其余3个线程
        pthread_join(tid2, NULL);
        pthread_join(tid3, NULL);
        return 0;
    }

    实验结果

    这里写图片描述

    结果分析:

    通过实验结果可以看到,在线程3阻塞前后,线程1 和 2 的运行状态没有任何变化。可以说明 一个线程的阻塞并不会导致所有线程都阻塞。

    2).不阻塞线程,阻塞进程,看其他线程是否阻塞,若其他线程也阻塞,则说明进程阻塞会导致所有线程阻塞。反之则反。

    #include <stdio.h>
    #include <pthread.h>
    
    
    void* run()
    {
        while(1)
        {
            sleep(1);
            printf("thread running ..\n");
        }
    }
    
    int main()
    {
        pthread_t tid1;
        pthread_create(&tid1, NULL, run, NULL);
    
        int input;
        scanf("%d", &input);
        printf("input is %d \n", input);
    
    
        while(1)
        {
            sleep(1);
            printf("main thread running.. \n");
        }
        return 0;
    }
    

    实验结果
    线程实验2

    结果分析:

    第二个实验就有点尴尬,因为严格意义上来说在现在的实验环境中让进程阻塞,也只能让主线程阻塞,而主线程除了结束的时候会导致整个进程都结束,和别的线程没有什么大的区别。因此实验结果和实验1区别并不大。


    第一部分到此结束。

    展开全文
  • Linux C 线程等待

    千次阅读 2013-10-08 19:47:13
      ...linux 下面的sleep,usleep,nanosleep 和select比较 sleep 时间单位是秒 usleep的时间单位是微秒 select的精度是微妙,精确 struct timeval delay; delay.tv_



    http://blog.csdn.net/wind19/article/details/7541811

     

    linux 下面的sleep,usleep,nanosleep 和select比较


    sleep 时间单位是秒

    usleep的时间单位是微秒

    select的精度是微妙,精确

    struct timeval delay;
    delay.tv_sec 
    = 0;
    delay.tv_usec 
    = 20 * 1000// 20 ms
    select(0, NULL, NULL, NULL, &delay);

    usleep()有有很大的问题

    1. 在一些平台下不是线程安全,如HP-UX以及Linux
    2. usleep()会影响信号
    3. 在很多平台,如HP-UX以及某些Linux下,当参数的值必须小于1 * 1000 * 1000也就是1秒,否则该函数会报错,并且立即返回。
    4. 大部分平台的帮助文档已经明确说了,该函数是已经被舍弃的函数。

    还好,POSIX规范中有一个很好用的函数,nanosleep(),该函数没有usleep()的这些缺点,它的精度是纳秒级。在Solaris的多线程环境下编译器会自动把usleep()连接成nanosleep()

    Linux下短延时推荐使用select函数,因为准确.



    ******************************************************************************************




    http://blog.csdn.net/horstlinux/article/details/7911457

    linux多线程编程,替代sleep的几种方式

    我只想要进程的某个线程休眠一段时间的,可是用sleep()是将整个进程都休眠的,这个可能就达不到,我们想要的效果了。 目前我知道有三种方式:

    1 usleep

       这个是轻量级的, 听说能可一实现线程休眠, 我个人并不喜欢这种方式,所以我没有验证它的可行信(个人不推荐)。

    2 select

       这个可以,我也用过这种方式, 它是在轮询。

    3  pthread_cond_timedwait

            采用pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t *mutex, const struct timespec *abstime)可以优雅的解决该问题,设置等待条件变量cond,如果超时,则返回;如果等待到条件变量cond,也返回。本文暂不将内部机理,仅演示一个demo。

           首先,看这段代码,thr_fn为一个线程函数:

    1. #include <stdio.h>  
    2. #include <stdlib.h>  
    3.   
    4. int flag = 1;  
    5. void * thr_fn(void * arg) {  
    6.   while (flag){  
    7.     printf("******\n");  
    8.     sleep(10);  
    9.   }  
    10.   printf("sleep test thread exit\n");  
    11. }  
    12.    
    13. int main() {  
    14.   pthread_t thread;  
    15.   if (0 != pthread_create(&thread, NULL, thr_fn, NULL)) {  
    16.     printf("error when create pthread,%d\n", errno);  
    17.     return 1;  
    18.   }  
    19.    
    20.   char c ;  
    21.   while ((c = getchar()) != 'q');  
    22.    
    23.   printf("Now terminate the thread!\n");  
    24.   flag = 0;  
    25.   printf("Wait for thread to exit\n");  
    26.   pthread_join(thread, NULL);  
    27.   printf("Bye\n");  
    28.   return 0;  
    29. }  
       输入q后,需要等线程从sleep中醒来(由挂起状态变为运行状态),即最坏情况要等10s,线程才会被join。采用sleep的缺点:不能及时唤醒线程。
    采用pthread_cond_timedwait函数实现的如下:

    1. #include <stdio.h>  
    2. #include <sys/time.h>  
    3. #include <unistd.h>  
    4. #include <pthread.h>  
    5. #include <errno.h>  
    6.    
    7. static pthread_t thread;  
    8. static pthread_cond_t cond;  
    9. static pthread_mutex_t mutex;  
    10. static int flag = 1;  
    11.    
    12. void * thr_fn(void * arg)   
    13. {  
    14.   struct timeval now;  
    15.   struct timespec outtime;  
    16.   pthread_mutex_lock(&mutex);  
    17.   while (flag) {  
    18.     printf("*****\n");  
    19.     gettimeofday(&now, NULL);  
    20.     outtime.tv_sec = now.tv_sec + 5;  
    21.     outtime.tv_nsec = now.tv_usec * 1000;  
    22.     pthread_cond_timedwait(&cond, &mutex, &outtime);  
    23.   }  
    24.   pthread_mutex_unlock(&mutex);  
    25.   printf("cond thread exit\n");  
    26. }  
    27.    
    28. int main(void)   
    29. {  
    30.   pthread_mutex_init(&mutex, NULL);  
    31.   pthread_cond_init(&cond, NULL);  
    32.   if (0 != pthread_create(&thread, NULL, thr_fn, NULL)) {  
    33.     printf("error when create pthread,%d\n", errno);  
    34.     return 1;  
    35.   }  
    36.   char c ;  
    37.   while ((c = getchar()) != 'q');  
    38.   printf("Now terminate the thread!\n");  
    39.   
    40.   pthread_mutex_lock(&mutex);  
    41.   flag = 0;  
    42.   pthread_cond_signal(&cond);  
    43.   pthread_mutex_unlock(&mutex);  
    44.   printf("Wait for thread to exit\n");  
    45.   pthread_join(thread, NULL);  
    46.   printf("Bye\n");  
    47.   return 0;  
    48. }  

            pthread_cond_timedwait()函数阻塞住调用该函数的线程,等待由cond指定的条件被触发(pthread_cond_broadcast() or pthread_cond_signal())。

            当pthread_cond_timedwait()被调用时,调用线程必须已经锁住了mutex。函数pthread_cond_timedwait()会对mutex进行【解锁和执行对条件的等待】(原子操作)。这里的原子意味着:解锁和执行条件的等待是原则的,一体的。(In this case, atomically means with respect to the mutex andthe condition variable and other access by threads to those objectsthrough the pthread condition variable interfaces.)

           如果等待条件满足或超时,或线程被取消,调用线程需要在线程继续执行前先自动锁住mutex,如果没有锁住mutex,产生EPERM错误。即,该函数返回时,mutex已经被调用线程锁住。

           等待的时间通过abstime参数(绝对系统时间,过了该时刻就超时)指定,超时则返回ETIMEDOUT错误码。开始等待后,等待时间不受系统时钟改变的影响。

           尽管时间通过秒和纳秒指定,系统时间是毫秒粒度的。需要根据调度和优先级原因,设置的时间长度应该比预想的时间要多或者少点。可以通过使用系统时钟接口gettimeofday()获得timeval结构体。





    展开全文
  • linux多线程的创建与等待详解

    千次阅读 2017-05-10 09:41:23
    所有线程都有一个线程号,也就是Thread ID。其类型为pthread_t。通过调用pthread_self()函数可以获得自身的线程号。 下面说一下如何创建一个线程。 通过创建线程线程将会执行一个线程函数,该线程格式必须按照...
  • 线程就有个执行流;一个进程至少有一个线程 2. 图解线程 PCB1所代表的进程通过vfork创建一个子进程,子进程再vfork一个新的子进程,以此类推产生两个新的子进程; 此时PCB1、PCB2、PCB3都指向同一块虚拟...
  • linux下的C语言开发(线程等待)

    千次阅读 2016-07-07 11:10:23
    线程等待
  • linux多线程编程中,如果线程A创建了线程B,我知道用pthread__ join可以令线程A 阻塞然后等待线程B的退出。如果线程A创建了三个线程B,C,D,执行完的先后顺序不知。想让A必须等待三个线程都退出后再退出,应该怎么做...
  • windows和linux多线程的一些区别

    万次阅读 热门讨论 2006-09-04 11:48:00
    我认为linux多线程不如windows。理由如下:一、功能WaitForSingleObject在linux下可以用pthread_cond_wait来替代实现,但是pthread_cond_wait不能用来等待thread handle。要等待thread handle可以用pthread_join,...
  • Linux线程间通信方式总结

    千次阅读 2017-12-05 16:07:45
    Linux系统中的线程间通信方式主要以下几种: * 锁机制:包括互斥锁、条件变量、读写锁和自旋锁。  互斥锁确保同一时间只能有一个线程访问共享资源。当锁被占用时试图对其加锁的线程都进入阻塞状态(释放CPU资源使...
  • Linux 线程挂起与唤醒功能 实例

    万次阅读 2015-04-03 08:54:22
    多线程的条件变量 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的...
  • 1)查看线程情况: #ps -T -A -o pid,ppid,pgid,etime,nice,rgroup,ruser,time,vsz,rss,args 2)查看进程情况: #ps -A -o pid,ppid,pgid,etime,nice,rgroup,ruser,time,vsz,rss,args
  • Linux多线程编程(一)---多线程基本编程

    万次阅读 多人点赞 2020-03-19 13:20:49
    线程是指运行中的程序的调度单位。一个线程指的是进程中一个单一顺序的控制流,也被称为轻量级线程。它是系统独立调度和分配的基本单位。...一个进程可以有很多线程,每个线程并行执行不同的任务。
  • 我只想要进程的某个线程休眠一段时间的,可是用sleep()是将整个进程都休眠的,这个可能就达不到,我们想要的效果了。 目前我知道有三种方式: 1 usleep  这个是轻量级的, 听说能可一实现线程休眠, 我个人并不...
  • linux线程资源回收方法

    万次阅读 2014-04-28 17:25:51
    Linux系统中程序的线程资源是有限的,表现为对于一个程序其能同时运行的线程数是有限的。而默认的条件下,一个线程结束后,其对应的资源不会被释放,于是,如果在一个程序中,反复建立线程,而线程又默认的退出,则...
  • 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁...
  • Linux线程的概念和使用

    万次阅读 2017-06-10 11:37:38
    我们并不可以开辟多个进程执行我们的操作(32位机器里每个进程认为它 独享 4G的内存资源),此时便引入了线程,例如当我们既需要下载内容,又需要浏览网页时,此时多线程便起了作用。线程是承担调度的基本单位,一个...
  • Linux线程退出方式总结

    万次阅读 2016-02-18 11:05:07
    在编写多线程代码时,经常面临线程安全退出的问题。 一般情况下,选择检查标志位的方式: 在线程的while循环中,执行完例程后,都对标志位进行检查,如果标志位指示继续执行则再次执行例程,如果标志位设置为退出...
  • Linux Shell脚本 多线程

    千次阅读 2015-09-13 22:28:11
    在bash中,我们通过后台运行(&)实现多线程。 for((i=1;i;i++)) do mongo="mongo_00$i" acmeair_web="acmeair_web_00$i" { docker run --name $mongo -d -p $port_m:27017 mymongodb docker run -d -p $port:...
  • linux多线程操作,互斥锁,条件锁

    万次阅读 2017-03-30 17:51:09
    Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多线程 API 有一些细微和隐晦的差别。不注意这些 Linux 上的一些开发陷阱,常常会导致程序问题不穷,死锁不断。本文中我们从 5 个方面总结出 Linux ...
1 2 3 4 5 ... 20
收藏数 156,478
精华内容 62,591
关键字:

linux线程等待