linux下线程
时间:2015-06-05 10:14:43
收藏:0
阅读:225
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,足见这是各个线程私有的数据。
原文:http://blog.csdn.net/zmrlinux/article/details/46370067
评论(0)