什么是线程?
一个程序内的多个执行线路被称之为线程。更为精确的定义是线程是一个进程内的控制队列。到目前为止我们所看到的所有程序都是作为单个进程来执行的,尽管与 许多其他的操作系统相类似,Linux具有同时运行多个进程的能力。确实,所有的进程至少有一个执行线程。在本书中到目前为止我们所看到的所有进程都只有 一个执行线程。
分清fork系统调用与新线程的创建是很重要的。当一个进程执行一个fork系统调用,就创建一个进程拷贝,具有其自己的变量与PID。这个新进程是单独 调度的,而且(通常如此)其执行是与创建他的进程相独立的。当我们在进程内创建一个新的线程,新线程的执行拥有其自己的堆栈(因而具有局部变量),但是共 享全局变量,文件描述符,信号处理器,而且其当前目录与创建他的进程相同。
线程的优点
1、创建一个新线程的代价要比创建一个新进程小得多
2、与进程之间的切换相比,线程之间的切换需要操作系统做的工作少得多
3、线程占用的资源要比进程少得多
4、能充分利用多处理器的可并行数量
5、在等待慢速I/O操作结束的同时,程序可执行其他的计算任务
6、计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
7、I/O密集型应用,为了提高系统,将I/O操作重叠。线程可以同时等待不同的I/O操作
线程的缺点
1、性能损失
一个很少被外部事件阻塞的计算密集型线程往往无法与其他线程共享同一个处理器。如果计算密集型线程的数量比可用的处理器多,那么可能会有较大的性能损失,这里的性能损失指的是增加了额外的同步和调度开销,而可用的资源不变。
2、健壮性降低
编写多线程需要更全面更深入的考虑,在一个多线程程序里,因时间分配上的细微偏差或者因共享了不该共享的变量而造成不良的可能性是很大的,换句话说线程之间是缺乏保护的。
3、缺乏访问控制
进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造成影响。
4、编程难度提高
编写与调试一个多线程比单线程程序困难得多
====================================================
相关函数:
1、创建一个新的线程
pthread_create函数
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
参数:
thread:返回线程ID
attr:设置线程的属性,attr为NULL表示使用默认属性
start_routine:是个函数地址,线程启动后要执行的函数
arg:传给线程启动函数的参数
返回值:成功0,失败返回错误码
2、等待线程结束
pthread_join函数
原型:
int pthread_join(pthread_t thread, void **retval);
参数:
thread:线程ID
retval:它指向一个指针,后者指向线程的返回值
返回值:成功0,失败返回错误码
3、线程终止
pthread_exit函数
原型:
void pthread_exit(void *value_ptr);
参数:
value_ptr:value_ptr不要指向一个局部变量。
4、返回线程ID
pthread_self函数
原型:
pthread_t pthread_self(void);
返回值:成功返回0
====================================================
#include <stdio.h>
#include <pthread.h>
// int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
void *func1(void *arg)
{
static char *p="ti is run out";
printf("t1:%ld thread is create\n",(unsigned long)pthread_self());
printf("t1:param is %d\n",*((int *)arg));
pthread_exit((void *)p);
}
int main()
{
int ret;
int param=100;
pthread_t t1;
char *pret=NULL;
ret=pthread_create(&t1,NULL,func1,(void *)¶m);
if(ret==0){
printf("main:create t1 success\n" );
}
printf("main:%ld\n",(unsigned long)pthread_self());
pthread_join(t1,(void **)&pret);
printf("main:t1 quit:%s\n",pret);
return 0;
}
====================================================
#include <stdio.h>
#include <pthread.h>
// int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
void *func1(void *arg)
{
static int ret=10;
printf("t1:%ld thread is create\n",(unsigned long)pthread_self());
printf("t1:param is %d\n",*((int *)arg));
pthread_exit((void *)&ret);
}
int main()
{
int ret;
int param=100;
pthread_t t1;
int *pret;
ret=pthread_create(&t1,NULL,func1,(void *)¶m);
if(ret==0){
printf("main:create t1 success\n" );
}
printf("main:%ld\n",(unsigned long)pthread_self());
pthread_join(t1,(void **)&pret);
printf("main:t1 quit:%d\n",*pret);
return 0;
}