linux C总结篇(线程)上
来源:互联网 发布:大数据修炼系统txt 编辑:程序博客网 时间:2024/06/07 03:21
(百度百科来凑数的,哈哈~~~) 线程:有时被称为轻量级进程,是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。
创建线程:
创建线程函数:
#include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
参数说明:1. thread:pthread_t类型的指针 ,用来返回所创建的线程的ID (非负数)
2.attr :指定线程的属性。默认为NULL 。稍后介绍
3.start_routine:线程创建后所要调用的函数,这是一个函数指针。
插曲( 指针函数与函数指针的简单区别):
指针函数:int *f(int a, int b);
函数指针:int (*f)(int a, int b);
说明: 函数指针就是用括号把你的函数名括起来,加一个*号。指针函数就是加一个*号
4.arg:传递给线程函数的参数 。
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<pthread.h>typedef struct { int a; int b;}TT ;void *creat_pthread(void *arg){ TT *p = (TT *)arg; pthread_t newthid ; int i; newthid=pthread_self() ; printf("the new pthread ID is %u \n",newthid) ; for(i= 0 ;i< (p->a) ; i++ ) printf("---------------------------%d\n",i ); return NULL ;}int main(void){ TT *p = (TT *)malloc(sizeof(TT)) ;//注意开辟空间,我就被坑在这里了@~@ pthread_t thid ; int n ,i; p->a= 100 ; p->b= 30 ; printf("%d %d\n",p->a,p->b); printf("the main pthread ID is %u \n",pthread_self()) ; if(pthread_create(&thid ,NULL ,creat_pthread ,(void *)p) != 0) { printf("creat pthread is failed !! \n"); exit(-1); } for(i= 0;i< 100;i++) printf("+++++++++++++++++++++++%d\n",i); sleep(5); exit(0);}
执行结果:
注意事项:
1.如果调用函数返回一个void 指针,则不需要强转。
2. 参数arg ,必须强转为void * 的类型,然后再在调用函数中转回来即可
3.传递多个参数时,必须申明一个结构体来包含所有的参数,然后再传入线程函数其实也是一个封装的思想了
4.结果也说明,线程执行顺序是不确定的,是由CPU 的调度算法(时间片的分配)所决定的 。
一些简单函数的说明:
pthread_t pthread_self(void);//取得本线程ID int pthread_equal(pthread_t t1, pthread_t t2);//判断两个线程ID 是否指向同一个线程 int pthread_once(pthread_once_t *once_control,void (*init_routine)(void)); //保证init_routine 线程函数在进程中只执行一次
线程属性 :
该结构体是
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;
参数说明:
schedpolicy:线程调度策略,只要有三种:(1)正常非实时。(2):实时,轮转。(3):实时,先入先出。(后两种调度只对root 用户有效)
schedparam :一个struct sched_param 结构体,其中有一个sched_priority 表示线程优先级,只有当调度策略为实时才有效,缺省为0
scope:线程优先级有效范围
线程终止(两种):
1.return 返回
2. 使用pthread_exit()函数:
#include <pthread.h> void pthread_exit(void *retval);
两种特殊情况:
1.在主线程中线程过早返回或者是调用exit 函数,则整个进程都会终止。就会导致所有的线程终止 。
2.在主线程中线程调用pthread_exit函数退出,进程不会结束,直到所有线程结束,进程才会结束
资源释放:
有些资源必须在一段时间内被一个线程所持有,其他线程使用资源时提出申请,也就是我所说的厕所的问题。现在我们假设一种情况,如果一个线程在终止时并没有释放资源,那么其他线程也无法使用,这就会导致死锁!!那么linux 该如何解决这个问题呐???
linux 系统提供了一对函数用于主动释放资源
#include <pthread.h> 1.void pthread_cleanup_push(void (*routine)(void *), void *arg); 2.void pthread_cleanup_pop(int execute);
说明:1.这两个函数的调用之间的程序段中的终止动作都会执行pthread_cleanup_push所指定的清除函数。
2.pthread_cleanup_push带有一个{ ,pthread_cleanup_pop带有一个},因此这两个函数必须成对出现,且必须位于程序的同一段代码中才能编译通过。
线程间的同步(相当于进程中的wait 函数)
#include <pthread.h> int pthread_join(pthread_t thread, void **retval);
说明:1.pthread_join用来等待一个线程的结束,调用pthread_join的线程被挂起,回收所等待线程的资源。
2.一个线程只允许一个线程使用pthread_join来等待
3.被等待的线程应该处于”join”的状态,而非死亡状态(DETACHED)
4.为避免内存泄漏,因此所有的线程终止时,必须处于两种情况之中(1.死亡状态(DETACHED)2.使用pthread_join和回收资源)
小示例:
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<pthread.h>int *creat_pthread(int *n ){ pthread_t newthid ; int i; newthid=pthread_self() ; printf("the new pthread ID is %d \n",newthid) ; for(i= 0 ;i< *n ;i++) printf("------------------------%d\n",i ); pthread_exit((void *)-100);}int main(void){ pthread_t thid ; int n ,i; int status ; printf("main pthread ID is %d \n",pthread_self()); printf("please input the n : "); scanf("%d",&n); if(pthread_create(&thid ,NULL ,(void *)creat_pthread ,&n) != 0) { printf("creat pthread is failed !! \n"); exit(-1); } pthread_join(thid,(void *)&status); printf("the new pthread's exit number is %d \n",status); exit(0);}
执行结果:
说明:1.status 存放新开的线程的退出码(-100)
2.pthread_join 阻塞主线程,等待新开的线程结束。(类似于函数的调用)
感觉后面的要介绍的内容过于多了一点,因此分成两个部分来叙述。望谅解!!!
阅读全文
1 0
- linux C总结篇(线程)上
- linux C 总结篇(线程)下
- Linux-c 线程总结
- Linux C进程总结(上)
- Linux C线程总结(1)
- Linux C线程总结(2)
- Java中Thread线程总结(上)
- java 线程总结上
- 线程控制(linux C)
- linux系统编译链接总结--高级c/c++编译技术读后总结(上)
- linux c之使用pthread_create创建线程pthread_join等待线程和pthread_exit终止线程总结
- linux线程实现机制(上)
- C#---线程池学习总结(未完。。。。)
- linux C总结篇(进程)
- linux C总结篇(信号)
- Linux C 总结篇(socket编程)
- Linux C 定时器 篇(四)单线程多定时器
- Linux C语言编程-Linux数据库操作--Linux上C语言操作SQLServer---知识点总结+实例
- dd iso
- 单例
- 递归经典算法 汉诺塔问题
- ceil函数
- 实体类和JSON对象之间相互转化
- linux C总结篇(线程)上
- Hdu-6053 TrickGCD(莫比乌斯函数)
- 数据结构单链表的相关操作(linux下实现)C语言
- 机器视觉系统不同检测场景的光源选择技巧
- 摄影小技巧
- 2.css基础知识
- Hibernate笔记
- html css知识大全
- Struts 注解配置例子及redirect,redirectAction,chain的区别