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 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线程等待与分离

    2020-05-19 20:59:27
    线程等待原因 已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。创建新的线程不会复用刚才退出线程的地址空间。 线程等待函数:pthread_join (1)功能:等待线程结束 (2)原型:int pthread_join...
    线程等待原因

    已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。创建新的线程不会复用刚才退出线程的地址空间。

    线程等待函数:pthread_join

    (1)功能:等待线程结束

    (2)原型:int pthread_join(pthread_t pthread, void **value_ptr);

    (3)参数:
    a.thread:线程ID;
    b.Value_ptr:它指向一个指针,后者指向线程的返回值。
    (4)返回值:成功返回0;失败返回错误码

    线程终止状态

    调用pthread_join函数的线程将挂起等待,直到ID为thread的线程终止。thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,总结如下:
    1)如果thread线程通过return返回,value_ptr所指向的单元里存放的是thread线程函数的返回值。
    2)如果thread线程被别的线程调用pthread_cancel异常终止,value_ptr所指向的单元里存放的是常数PTHREAD_CANCELED。
    3)如果thread线程是自己调用pthread_exit终止的,value_ptr所指向的单元存放的是传给pthread_exit的参数。
    4)如果对thread线程的终止状态不感兴趣,可以传NULL给value_ptr参数

    在这里插入图片描述

    #include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
    #include<pthread.h>
    #include<unistd.h>
    void *thread1(void *arg)
    {
        printf("thread 1 returning...\n");
        int *p = (int *)malloc(sizeof(int));
         *p = 1;
        return (void*)p;
    }
    void *thread2(void *arg)
    {
        printf("thread 2 exiting ...\n");
        int *p = (int *)malloc(sizeof(int));
        *p = 2;
        pthread_exit((void*)p);
    }
    void *thread3(void *arg)
    {
         while(1){
            printf("pthread 3 running ...\n");
            sleep(1);
     }
        return NULL;
    }
    int main(void)
    {
        pthread_t tid;
        void *ret;
        pthread_create(&tid, NULL, thread1, NULL);
        pthread_join(tid, &ret);
        printf("thread return, thread id %X, return code:%d\n", tid, *(int*)ret);
        free(ret);
        
        pthread_create(&tid, NULL, thread2, NULL);
        pthread_join(tid, &ret);
        printf("thread return, thread id %X, return code:%d\n", tid, *(int*)ret);
        free(ret);
        
        pthread_create(&tid, NULL, thread3, NULL);
        sleep(3);
        pthread_cancel(tid);
        pthread_join(tid, &ret);
        if(ret == PTHREAD_CANCELED)
           printf("thread return, thread id %X, return code:PTHREAD_CANCELED\n", tid);
        else
           printf("thread return, thread id %X, return code:NULL\n", tid);
    
    }
    分离线程

    1)默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成内存泄漏。

    2)如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。

    int pthread_detach(pthread_t pthread);

    注意:可以是线程组内其他线程对目标线程进行分离,也可以是线程自己分离;pthread_detach(pthread_self());
    joinable和分离是冲突的,一个线程不能既是joinable又是分离的。

    代码:

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<string.h>
    #include<pthread.h>
    
    void *thread_run(void *arg)
    {
        pthread_detach(pthread_self());
        printf("%s\n", (char*)arg);
        return NULL;
    }
    
    int main()
    {
        pthread_t tid;
        if(pthread_create(&tid, NULL, thread_run, "thread1 run...") != 0){
            printf("create thread error\n");
            return 1;
        }
    
        int ret = 0;
        sleep(1);
    
        if(pthread_join(tid, NULL) == 0){
            printf("pthread wait success\n");
            ret = 0;
        }else{
        printf("pthread wait failed\n");
            ret = 1;
        }
        return ret;
    
    }
    展开全文
  • 线程等待 为什么需要线程等待? 已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。 创建新的线程不会复⽤刚才退出线程的地址空间。 线程退出也需要保存自己的退出返回值,因此线程也需要等待。只有...
  • 线程就有个执行流;一个进程至少有一个线程 2. 图解线程 PCB1所代表的进程通过vfork创建一个子进程,子进程再vfork一个新的子进程,以此类推产生两个新的子进程; 此时PCB1、PCB2、PCB3都指向同一块虚拟...
  • linux下的C语言开发(线程等待)

    千次阅读 2016-07-07 11:10:23
    线程等待
  • pthread_cond_timedwait()函数和pthread_cond_wait()函数,其实2个函数都差不多,我主要是要用pthread_cond_timedwait()函数。 pthread_cond_timedwait()函数有三个入口参数: (1)pthread_cond_t __cond:条件变量...
  • linux多线程的创建与等待详解

    千次阅读 2017-05-10 09:41:23
    所有线程都有一个线程号,也就是Thread ID。其类型为pthread_t。通过调用pthread_self()函数可以获得自身的线程号。 下面说一下如何创建一个线程。 通过创建线程线程将会执行一个线程函数,该线程格式必须按照...
  • linux 线程等待队列

    千次阅读 2013-05-09 20:14:36
    假如有线程正在阻塞等待着这个条件变量的话,那么是根据各等待线程优先级的高低确定哪个线程接收到信号开始继续执行。 如果各线程优先级相同,则根据等待时间的长短来确定哪个线程获得信号。但无论如何一个...
  • 例如A线程等待B线程,需要实现等待超时机制。解决方案是利用条件变量实现。 1. 条件变量  条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了...
  • Linux线程编程 - 线程退出与等待

    千次阅读 2016-08-26 16:17:40
    线程退出 新创建的线程从执行用户定义的函数处开始执行,直到出现以下情况时退出: 调用pthread_exit函数退出。调用pthread_cancel函数取消该线程。...等待线程 退出线程示例 [cpp] view plai
  • pid:所等待线程ID; value_ptr:通常设置为NULL,如果不为NULL,pthread_join将复制一份线程退出值到一个内存区域,并让*value_ptr指向该内存。 返回值:执行成功返回0,否则返回错误码。 2、作用 pthread_...
  • 其实可以将线程等待类比于进程等待,要是子进程都退出了,而父进程还不知道,不能及时回收子进程的资源,就让子进程变成了一个僵尸进程,说到底我们的线程等待和进程等待都是为了回收资源,资源很宝贵我们不能随意...
  • linux线程及线程同步(锁的应用)

    千次阅读 2018-08-23 08:28:18
    linux原本没有线程,后来在windows多线程编程影响下linux内核开发者在进程基础上在功能上做出了类似windows线程的linux版本的线程,linux线程归根到底还是进程,只不过是轻量级的进程,开销比真正进程要小得多,...
  • 线程等待: 函数:pthread_join extern int pthread_join __P (pthread_t __th, void **__thread_return); 参数: 第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的...
  • Linux线程部分总结分为两部分:(1)线程的使用 ,(2)线程的同步与互斥。 第一部分线程的使用主要介绍,线程的概念,创建线程,线程退出,以及线程的终止与分离。第二部分主要介绍在多线程环境下,使用同步与互斥...
  • linux多线程编程中,如果线程A创建了线程B,我知道用pthread__ join可以令线程A 阻塞然后等待线程B的退出。如果线程A创建了三个线程B,C,D,执行完的先后顺序不知。想让A必须等待三个线程都退出后再退出,应该怎么做...
  • 【 声明:版权所有,欢迎转载,请勿用于商业用途。... 和多进程一样,多线程也有自己的等待函数。这个等待函数就是pthread_join函数。那么这个函数有什么用呢?我们其实可以用它来等待线程运行结束。
  • linux多线程编程是指基于Linux操作系统下的多线程编程,包括多任务程序的设计,并发程序设计,网络程序设计,数据共享等。Linux系统下的多线程遵循POSIX线程接口,称为pthread。编写Linux下的多线程程序,需要使用...
1 2 3 4 5 ... 20
收藏数 156,012
精华内容 62,404
热门标签
关键字:

linux线程等待