【Linux】 Pthread的基本使用

目录

1  创建一个线程------以阻塞在pthread_join()的方式结束运行。

2  创建一个线程------pthread_detach()以主子线程分离的方式运行。

3  证明主线程和创建的子线程同时执行(即能够交替打印1,2)


  • 函数原型:int pthread_create( pthread_t *thread,  const pthread_attr_t *attr,  void *(*start_routine) (void *),  void *arg);

                 功能:创建一个线程(成功返回<0, 失败返回 > 0.)
                 参数:线程ID,线程属性 (一般不用为NULL),线程执行函数  ,线程执行函数参数

  • 函数原型:int pthread_exit(void *retval);

                功能:在创建的线程中调用,代表结束当前线程。
                参数:   局部变量 返回指针

                      在main线程中调用pthread_exit会起到只让main线程退出,但是保留进程资源,供其他由main创建的线程使用,直至所有线程都结束。

  • pthread_join()和pthread_detach()只能使用一个:他们各自决定了子线程以什么方式结束。只能选其一。

1  创建一个线程------以阻塞在pthread_join()的方式结束运行。

  • 函数原型:int pthread_join(pthread_t thread, void **thread_return);

                功能:等待线程的结束   (成功返回0,失败返回其他)

                          pthread_join()即是子线程(Thread_A)合入主线程(main),主线程阻塞等待子线程结束,然后回收子线程资源。感觉是把子线程当作一个函数调用。
                参数:   线程ID(要结束的线程),线程退出的时候的返回参数指针

#include "stdio.h"
#include "unistd.h"
#include "stdlib.h"
#include "string.h"
#include "pthread.h"

char message[] = "hello world";

void *Thread_A(void* arg)
{
   printf("thread is running!!!!\n");
   sleep(3);
   strcpy(message, "Bye");// message[] == "Bye"
   pthread_exit("Thank you using CPU!!!!!!\n");//退出当前线程,并且返回字符串
}


int main()
{
    int res;
    pthread_t a_thread;
    void *thread_result;
    
    res = pthread_create(&a_thread, NULL, Thread_A, message);//创建线程---1
    if(res != 0){  printf("error create thread");  }
    printf("thread waiting for finish \n");
    
    res = pthread_join(a_thread, &thread_result);//thread_result为pthread_exit()传入的字符串  
                                                 //main卡在此处,等待Thread_A执行结束
    if(res != 0){  printf("error thread join "); }
    printf("thread joined, it returned %s ", (char*)thread_result);

    printf("message is %s \n", message); 
}

2  创建一个线程------pthread_detach()以主子线程分离的方式运行。

2.1 法1---先创建一个默认join态的线程,再改为detach态

  • 函数原型:int pthread_detach(pthread_t thread, void **thread_return);

                    功能:把主线程与子线程分开                          
                    参数:   线程ID/ pthread_myself(),线程退出的时候的返回参数指针

  • 在main线程中调用pthread_exit会起到只让main线程退出,但是保留进程资源,供其他由main创建的线程使用,直至所有线程都结束。   故调用了pthread_detach()和pthread_exit()后因为thread1有while(1),所以main结束后仍可一直运行子线程。
  • 子线程中加入代码pthread_detach(pthread_self())   或者父线程调用pthread_detach(thread_id) 均可将子线程与主线程分离。

#include <stdlib.h>
#include "stdio.h"
#include "unistd.h"
#include "stdlib.h"
#include "string.h"
#include "pthread.h"

void* thread1(void *arg)
{
    //pthread_detach(pthread_self());  //子线程写myself()
    while (1)
    {
        usleep(100 * 1000);
        printf("thread1 running...!\n");
    }
    printf("Leave thread1!\n");

    return NULL;
}

int main(int argc, char** argv)
{
    pthread_t tid;

    pthread_create(&tid, NULL, (void*)thread1, NULL);
    pthread_detach(tid);      // 使thread1线程处于分离状态一直运行
                              // 主线程写子线程tid
    
    printf("main running...!\n");
    sleep(1);
    printf("Leave main thread!\n");
    pthread_exit("end");     	//在main()中子线程退出。
				                //这个地方执行后,主线程main和子线程thread1因为已经分离了,而子线程有while(1)则会一直运行。
                                //若屏蔽此句,由main创建的子线程在执行retrun后,子线程也会被强制结束。

    return 0;
}

2.2 法2---直接创建一个detach态的线程。

  • 使用pthread_create()函数创建线程时,函数第二个参数为NULL,则使用线程属性的默认参数,若不为空,其中非分离属性需要程序退出之前运行pthread_join把各个线程归并到一起。可见上述第一个例子。如果想让线程向创建它的线程返回数据,就必须这样做。
  • 和上述的情况一样,不过是在创建线程的时候就把它的detach态配置好。而不是先创建一个默认join态的线程,再改为detach态。可尝试将上述的pthread_create(),pthread_detach(tid); 注释掉,插入以下代码会有一样的效果。
{
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED);   //配置在pthread_create()中要执行的线程的属性为detach,即可分离态
								       
}
    	pthread_create(&tid, &attr, (void*)thread1, NULL);  
  •  pthread_attr_destroy(pthread_attr_t *attr);    销毁由 pthread_attr_init(&attr)所分配的内存空间。

3  证明主线程和创建的子线程同时执行(即能够交替打印1,2)

#include "stdio.h"
#include "unistd.h"
#include "stdlib.h"
#include "string.h"
#include "pthread.h"

char message[] = "hello world";
int run_now = 1;

void *Thread_A(void* arg)
{
    int print_count2 = 0;
    while(print_count2++ < 20) {
        if (run_now == 2) {
            printf("2");//-----------3,7
            run_now = 1; 
        }
        else {  sleep(1);  }//在Sleep的时候,切换到a_thread进程------4,8
    }
}


int main()
{
    int res;
    pthread_t a_thread;
    void *thread_result;
    
    res = pthread_create(&a_thread, NULL, Thread_A, message);// message[] == "hello world"
    if(res != 0){  printf("error create thread");  }

{
    int print_count1 = 0;
    while(print_count1++ < 20) {//程序进入此循环
        if (run_now == 1) {
            printf("1");//------------------1,5
            run_now = 2; 
        }
        else {  sleep(1);  }//在Sleep的时候,切换到a_thread进程----------2,6
    }
}

    printf("\n thread waiting for finish \n");
    
    res = pthread_join(a_thread, &thread_result);//thread_result == Thread_A return  "Thank you using CPU!!!!!!"
    if(res != 0){  printf("error thread join "); }
    printf("thread joined, it returned %s ", (char*)thread_result);

    printf("message is %s \n", message);

}


版权声明:本文为m0_37844072原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。