首页 > 代码库 > linux下线程

linux下线程

                                                                     linux下线程

线程与进程的关系:
之前转载的微信文章,进程与线程的差别已经说得比較清楚了。能够查看之前转载的文章。linux进程与线程的差别。
创建一个线程:
#include<pthread.h>
               int pthread_creat(pthread_t * thread,pthread_attr_t * attr,void *(*stat_routine)(void *),void *arg);
               惯例先写上函数原型:
參数:第一个參数pthread_t * thread 是一个指针,当进程创建时用来返回进程的ID。

    第二个參数pthread_attr_t * attr 用于指示线程的属性,默认就是NULL。
                                    第三个參数void *(*stat_routine)(void *),void *arg 这个參数为一个函数指针,指向线程创建后要调用的函数。
                                    第四个參数void *arg  该參数指向传递给线程函数的參数。
                      创建成功后返回0,失败返回错误码(非常多种。

。。cha)


几个其它实用的系统调用:
pthread_t pthread_self(void )                                                       获取本线程的ID
        int pthread_equal(pthread_t  thread,pthread_t thread2)           推断两个线程的ID是否指向同一个ID
        int pthread_once (pthread_once_t *once_count,void(*int_routine)(void))    用来保证线程的函数仅仅运行一次

一个运行一次函数的样例
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>

pthread_once_t once = PTHREAD_ONCE_INIT;          //指定參数位仅仅运行一次

void run(void)                                        //演示样例线程函数
{
	printf("function run is runing in thread %d\n",pthread_self());
}

void *thread1(void *arg)
{
	pthread_t thid = pthread_self();                   //接受而且打印当前线程的ID
	printf("current thread id is %d\n",thid);           //调用运行线程函数仅仅运行一次,接受一个标志參数和一个目标函数的指针
	pthread_once(&once,run);
	printf("thread1 ends\n");                           //打印函数调用结束提示信息
}

void *thread2(void *arg)
{
	pthread_t thid = pthread_self();                  //接受而且打印当前线程ID
	printf("current thread is ID %u\n",thid);
	pthread_once(&once,run);                         //调用函数同上以一个函数结构。可是这里并不会成功调用由于仅仅运行一次
	printf("thread2 ends\n");                         //打印函数调用结束信息
}
int main()
{
	pthread_t thid1,thid2;                             //定义两个线程ID
	pthread_create(&thid1,NULL,thread1,NULL);           //创建线程。调用上边的函数1和函数2
	pthread_create(&thid2,NULL,thread2,NULL);
	sleep(3);                                          //主线程(进程)暂停3秒后继续运行
	printf("main thread exit!\n");
	exit(0);
}

run 函数在线程thread1 中仅仅执行了一次。尽管thread2也调用了,然而并没有什么用

线程的属性:
pthread_attr_t 结构体

typedef struct

{

       int                              detachstate;   线程的分离状态

       int                              schedpolicy;  线程调度策略

       struct sched_param           schedparam;  线程的调度參数

       int                              inheritsched;  线程的继承性

       int                               scope;       线程的作用域

       size_t                          guardsize;   线程栈末尾的警戒缓冲区大小

       int                               stackaddr_set;

       void *                         stackaddr;   线程栈的位置

       size_t                          stacksize;    线程栈的大小

}pthread_attr_t;



线程的终止:
两种方式:
1.通过return返回
                        2.调用库函数
#include<pthread.h>
                       void pthread_exit(void *retval);
              当调用退出函数时需注意:
1.调用exit( )一个线程死亡,这个进程也会跟着死亡。
                2假设调用本函数那么不过主线程死亡,进程依旧存活。


pthread_join(pthread_t th,void * thread_return);
            这个函数用于等待一个线程的结束。

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

void assisthread(void *arg)                   //演示样例线程函数
{
	printf("i am nothing helping to do some thing\n");
	sleep(3);                                //暂停三秒
	//pthread_exit(0);     
	//线程结束
	exit(0);
}

int main()
{
	pthread_t   assisthid;
	int         status   ;

	pthread_create(&assisthid,NULL,(void *)assisthread,NULL);     //创建线程
	pthread_join(assisthid,(void *)&status);                      //等待指定线程结束
	printf("assistthread‘s exit is caused %d\n",status);

	return 0;

私有数据:
这个比較有意思。再说之前最好还是来说说error 这个东西。这是存储程序错误时返回的错误码的一个全局变量。之前上课时,有一个同学提问假设错误同一时候发生。那么两个进程都向这个变量中写入数据,会发生什么事情?会锁死。还是会覆盖?首先,这种事情基本不会发生。由于CPU仅仅有一个,就算有两个CPU同一时候处理这两个进程也非常难发生这种事,由于CPU的时间能够精确到10^-9次方秒。两个时间撞在一起真是比买彩票中奖还难。更何况就算发生了也没事。这是由与error事实上是一个私有数据。全局变量有这个变量名字叫做”键“,而每个线程都有一个error用来存储值,俗称一键多值。每个error是不影响的。
一段代码:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>

pthread_key_t key;          //定义全局变量,键

void *thread2(void *arg)        //第二个函数
{
	int tsd = 5;                   //自己线程的私有数据
	printf("thread %d is runing \n",pthread_self());
	pthread_setspecific(key,(void *)tsd);       //设置一个私有数据
	printf("thread %d return %d\n",pthread_self(),pthread_getspecific(key));
}

void *thread1(void *arg)//创建线程一然后调用函数二创建还有一个线程
{
	int tsd = 0;
	pthread_t thid2;

	printf("thread %d is runing\n",pthread_self());
	pthread_setspecific(key,(void *)tsd);
	pthread_create(&thid2,NULL,thread2,NULL);
	sleep(5);
	printf("thread %d return %d\n",pthread_self(),pthread_getspecific(key));
}

int main()
{
	pthread_t thid1;
	printf("main thread begins running\n");
	pthread_key_create(&key,NULL);              //创建一个键
	pthread_create(&thid1,NULL,thread1,NULL);   //调用函数一创建线程1
	sleep(3);
	pthread_key_delete(key);                    //删除键
	printf("main thread exit\n");
	return 0;
}

终于打印的值一个是5 一个是0,足见这是各个线程私有的数据。



linux下线程