进程与线程
进程:
首先进程是一个实体,每一个进程都有自己的内存地段,进程是执行中的程序,但程序是一个没有生命的实体。进程是操作系统中最基本的,最重要的概念。
线程:
线程包含了表示进程内执行环境必须的信息,包括标识线程的线程ID,一组寄存器值,栈,调度优先级和策略,信号屏蔽字,errno变量以及线程私有数据。
每一个程序至少有一个线程。一个进程在同一时间只能做一件事,多线程可以同时做多件事,每个线程可以处理不同的事物,一个线程阻塞,另一个线程并不会受到影响。
进程中的所有信息在线程中都是共享的,线程中有自己的栈。包括执行代码,全局变量,和堆内存,栈以及文件描述符。
线程创建:
在进程中只有一个控制线程即主线程,程序是以单线程启动的,在创建了多个线程以后,若用gcc编译的时候,需要在最后添加-lpthread选项,目地是(链接叫libpthread.oo这个库)
#include<pthread.h>
int pthread_create(pthread_t * thread,const pthread_attr_t * attr,void *(*start_routine)(void *),void * arg);
参数thread 是一个指针,当线程成功创建,返回创建线程的ID
参数addr 用于指定线程的属性,一般设为NULL(即表示此线程为不可分离状态);
参数start_routine 是一个函数指针,指向线程创建后要调用的函数(回调函数)
参数arg 传递给线程函数的参数
成功返回0
pthread_create实例1:
void *func(void *arg)
{
printf("pthread start\n");
return NULL;
}
int main(int arg, char * args[])
{
pthread_t thr_d;
int err = pthread_create(&thr_d, NULL, func, NULL);
if (err != 0)
{
printf("create pthread failed\n");
}
else
{
printf("create pthread success\n");
}
sleep(1);
return 0;
}
实例2:
void * func1(void * arg)
{
printf("pthread1 start\n");
sleep(1);
printf("pthread1 end\n")
return 0;
}
void * func2(void * arg)
{
printf("pthread2 start\n");
while(1)
{
printf("hehe\n");
sleep(1);
}
printf("pthread2 end\n")
return 0;
}
int main(void)
{
pthread_t thid1,thid2;
if(pthread_create(&thid1,NULL,func1,NULL) != 0)
{
printf("error is %s\n",strerror(errno));
}
if(pthread_create(&thid2,NULL,func2,NULL) != 0)
{
printf("error is %s\n",strerror(errno));
}
while(1)
{
sleep(1);
}
return EXIT_SUCCESS;
}
线程终止:
1 任何线程调用exit函数,整个进程会被杀死
2 调用pthread_exit()函数,使线程退出,进程并不会死
3 线程中使用return ;是线程退出
4 线程可以被同一进程中的其他线程取消,pthread_cancel
void pthread_exit(void *arg);
arg是一个无类型的指针,该指针会被其他线程调用
实例:
void *func(void *arg)
{
printf("pthread start\n");
pthread_exit(0);
}
int main(int arg, char * args[])
{
pthread_t thr_d;
pthread_create(&thr_d, NULL, func, NULL);
sleep(1);
return 0;
}
线程挂起:此函数用于挂起当前线程,直到th指定的线程终止为止
int pthread_join(pthread_t th,void ** thr_return);
参数:th 即线程ID,指定被挂起的线程ID号
参数:thr_return ,是指向线程th返回的指针,也可为null
pthread_join()实例:
void * func1(void * arg)
{
sleep(5);
return NULL;
}
int main()
{
pthread_t thid;
int i1 = 1,i2 = 2;
if(pthread_create(&thid,NULL,func1,&i1) != 0)
{
printf("error is %s\n",strerror(errno));
}
int *p = NULL;
//pthread_join的第二个参数是指向线程thid返回的指针
pthread_join(thid,(void **) &p);//pthread_join(thid,null);
printf("p = %d\n",*p);
printf("main end\n");
return 0;
}
pthread_cancel实例:
void *func1(void *arg)
{
printf("pthread%d start\n",i1);
while(1)
{
printf("thread%d is running\n",i1);
sleep(1);
}
pthread_exit(NULL);
}
void *func2(void *arg)
{
printf("pthread%d start\n",i2);
sleep(5);
pthread_cancel(thr_d1);
printf("pthread%d end\n",i2);
pthread_exit(NULL);
}
int main(int arg, char * args[])
{
pthread_t thr_d1,thr_d2;
int i1 = 1,i2 = 2;
pthread_create(&thr_d1, NULL, func1, &i1);
pthread_create(&thr_d2, NULL, func2, &i2);
sleep(6);
printf("end\n");
return 0;
}
int pthread_detach(pthread_t th);
实例:
void * func1(void * arg)
{
printf("child pthread start\n");
while(1)
{
sleep(1);
printf("child pthread end\n");
}
pthread_exit(0);
}
//线程退出有三种方法,其中之一可以是在一个线程中结束另一个线程pthread_cancel
void * func2(void * arg)
{
//因为线程ID为pthread_t类型,并不是一个整型
sleep(5);
pthread_t thr;
thr = *(pthread_t *) arg;
pthread_cancel(thr);
pthread_exit(0);
}
int main()
{
pthread_t thid1,thid2;
int i1 = 1,i2 = 2;
if(pthread_create(&thid1,NULL,func1,NULL) != 0)
{
printf("pthread error\n");
}
if(pthread_create(&thid2,NULL,func2,&thid1) != 0)
{
printf("pthread error\n");
}
pthread_detach(thid1);
pthread_join(thid2,NULL);
printf("main end\n");
return 0;
}
线程属性:
以前调用pthread_create传入的attr参数都是空指针,而不是指向pthread_attr_t结构的指针。
int pthread_attr_init(pthread_addr_t * attr); // 线程结构初始化函数
int pthread_attr_destroy(phttp://www.cnblogs.com/shichuan/p/4496160.htmlthread_attr_t *attr); // 释放attr内存空间的函数
int pthread_attr_setdetachstate(pthread_attr_t *attr,int detachstate);
// 参数detachstate有两个合法值,PTHREAD_CREATE_DETACHED 设置线程为分离状态
//PTHREAD_CREATE_JOINABLE 设置线程为正常状态
可以通过pthread_attr_t 在创建线程的时候就指定线程属性为分离状态,而不用创建以后再去修改线程属性。
使用步骤:
1 使用pthread_attr_init 函数初始化pthread_attr_t结构。
2 pthread_attr_setdetachstate(pthread_attr_t *attr,int detachstate);
3 pthread_attr_destroy(pthread_attr_t *attr);//释放attr内存空间
实例:
void *func(void *arg)
{
printf("pthread start\n");
while(1)
{
printf("thread is running\n");
sleep(1);
}
pthread_exit(NULL);
}
int main(int arg, char * args[])
{
pthread_t thr_d;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&thr_d, &attr, func, NULL);
pthread_attr_destroy(&attr);
sleep(2);
printf("end\n");
return 0;
}