线程: 在一个进程的地址空间中执行多个线程 ---- 强调共享 

   wKiom1cTJ36iqyIpAAAN-wynHmI710.png 线程是进程中的一个实体。


    线程私有: 线程id

         上下文信息 (包括各种寄存器的值、程序计数器和栈指针)

         (私有)栈空间    errno变量    信号屏蔽字    调度优先级


    此时:POSIX标准   编译时  加上 -lpthread



线程与进程的区别:

    1、进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位;

       线程是进程的一个实体。

    2、进程 强调 独占,线程 强调 共享。

    3、线程私有【 线程id

                  上下文信息 (包括各种寄存器的值、程序计数器和栈指针)

                  (私有)栈空间    errno变量    信号屏蔽字    调度优先级 】

    4、二者均可并发执行。


一、线程控制:

    

1、创建线程:

     int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

                          void *(*start_routine) (void *), void *arg);

                 //参数:线程 id,线程 属性,线程 状态,线程 参数

                 //返回值:成功 0;失败 错误码

2、等待线程:

       int pthread_join(pthread_t thread, void **retval); //参数:线程 id,返回值

3、终止线程:

     1)从线程函数内部 return 结束  //value_ptr指向的存放:return 返回值

     2)从线程函数调用 pthread_exit()函数      //value_ptr指向的存放:pthread_exit 参数

         void pthread_exit(void *retval);

     3)线程被取消 pthread_cancel()

         int pthread_cancel(pthread_t thread); //value_ptr指向的存放:PTHREAD_CANCELED (-1)

         pthread_t pthread_self(void); //线程id

实例:

//my_thread.c  

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

void *thread_run(void *arg)
{
//      sleep(10);
	int count=5;
	while(count-- > 0)
	{
		printf("this is thread,Code: %d\n",pthread_self());
		sleep(1);
	}
//	return (void*)1; //终止线程1:return
//	pthread_exit((void*)2); //终止线程2:pthread_exit
        return NULL; //终止线程3:pthread_cancel
}
int main()
{
	pthread_t tid; //主线程
	int ret=pthread_create(&tid,NULL,thread_run,NULL); //创建线程
	int count=10;
	while(count-- > 0)
	{
		printf("This is Main-Thread,Code: %d\n",pthread_self());
		sleep(1);
	}
	pthread_cancel(tid); //终止线程3:pthread_cancel

	void *status=0;
	ret=pthread_join(tid,&status);
	if(ret == 0)
	{
		printf("thread is success,Code: %d\n",(int)status);
	}

	return 0;
}

运行结果:

    终止线程:

            wKioL1cTeabQnRUeAADJSZSp4Is490.jpg

            wKiom1cTI--QpwcNAAALI4CcfTs514.jpg


         wKiom1cTed2zsCHSAACeaJbKYS8786.jpg

总结:

     终止进程的三种方法运行结果大体相同,但返回值不同,return 的返回值和exit的参数及PTHREAD_CANCELED (值为-1)。


二、线程分离:  线程的一种属性

     线程是可结合的(joinable)或者是分离的(detached)。

     由于调用pthread_join后,如果该线程没有运行结束,调用者会被阻塞,在有些情况下我们并不希望如此。这时可以在 子线程中加入代码     pthread_detach(pthread_self())

或者 父线程调用    pthread_detach(thread_id)(非阻塞,可立即返回)。

     这将该子线程的状态设置为分离的,这样一来,该线程运行结束后会自动释放所有资源。


//thread_detach.c

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

void* thread1(void *arg)
{
	int count=5;
	while(count-- > 0)
	{
		printf("this is thread1:%d,thread_t:%u\n",(int)arg,pthread_self());
		sleep(1);
	}
	return (void*)1;
}

void* thread2(void *arg)
{
	int count=5;
	while(count-- > 0)
	{
		printf("this is thread2:%d,thread_t:%u\n",(int)arg,pthread_self());
		sleep(1);
	}
	pthread_exit((void*)2);
}

void* thread3(void *arg)
{
	int count=5;
	while(count-- > 0)
	{
		printf("this is thread3:%d,thread_t:%u\n",(int)arg,pthread_self());
		sleep(1);
	}
	return NULL;	
}

int main()
{
	pthread_t tid1,tid2,tid3;
	pthread_create(&tid1,NULL,thread1,(void*)1);
	pthread_create(&tid2,NULL,thread2,(void*)2);
	pthread_create(&tid3,NULL,thread3,(void*)3);
	sleep(2);
	pthread_cancel(tid3);
	pthread_detach(tid1);

	void *ret=NULL;
	int res=pthread_join(tid1,&ret);
	printf("tid1 return,res:%d\n",res);
	res=pthread_join(tid2,&ret);
	printf("tid2 pthread_exit,res:%d\n",res);
	res=pthread_join(tid3,&ret);
	printf("tid3 pthread_cancel,res:%d\n",res);
	
	return 0;
}

运行结果:

    wKiom1cThA_i0qlnAADFWM06fAQ989.jpg