一、线程概念
进程和线程共同点:并发
1.线程属于某一个进程,线程不共享栈区
优点:比多进程节省资源,可以共享变量。
线程启动时,需要在栈区开一个8M的空间,进程拿到的资源,对于线程是共享的。
2.概念:线程是轻量级进程,一般是一个进程中的多个任务
进程是系统中最小的资源分配单位
线程是系统中最小的执行单位
3.区别:
1)线程的并发度比进程多一些
2)创建开销不同,thread 8M, proc 3G
3)thread 共享进程中的资源,除了栈区。进程,独立(写时复制 cow)
4)线程稳定性稍差。
5)进程可以申请到硬件资源,线程用进程拿到的资源
4.三方库: pthread clone posix(posix便于移植的)
4.1 编写代码头文件: pthread.h
4.2 编译代码加载库: -lpthread library
libpthread.so (lib开头so结尾,共享库)
gcc 1.c -lpthread
5.线程的设计框架
1.创建多线程 --->线程空间操作 --->线程资源回收
int pthread_create(
pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
eg: pthread_create(&tid, NULL, th, NULL);
2. arg 回调函数的参数,即参数3的指针函数参数。
返回值:成功 0
失败 错误码
6.pthrea_self(void)获取自己的tid号
7.线程的退出:
1: 自行退出 --> 自杀 --> 子线程自己退出 void pthread_exit(void *retval); exit return p;
2: 强制退出 --> 他杀 --> 主线程结束子线程 int pthread_cancel(pthread_t thread);
8.线程的回收
不同与进程没有孤儿线程和僵尸线程。
主线程结束任意生成的子线程都会结束。
子线程的结束不会影响主线程的运行。
int pthread_join(pthread_t, thread, void **retva)
join有阻塞的意思
功能:通过该函数可以将指定的线程资源回收,该函数具有阻塞等待功能,如果指定的线程没有结束,则回收线程会阻塞。
9.地址有三种:
0、栈区变量 错误,子线程结束该地址失效。
1、全局变量 失去意义,本质可以直接访问。
正确形式:
2、静态变量
3、堆区变量malloc
10.分离属性:
int pthread_deatch(pthread_t thread);
1)可以放在th里面调用,参数写自己的id号
2)主线程调用:填入刚才创建的线程的线程号。
11.线程清理函数
void pthread_cleanup_push(void (*routine)(void *), void *arg);
功能:注册一个线程清理函数
参数,routine,线程清理函数的入口
arg,清理函数的参数。
返回值,无
void pthread_cleanup_pop(int execute);
功能:调用清理函数
execute,非0 执行清理函数
0 ,不执行清理
12.线程起进程后,起完多线程就会变成单线程
二、练习及其代码
1.创造线程
#include
#include
#include
#include
#include
#include
void *th1(void *arg)
{
while (1)
{
printf("打瓦\n");
sleep(1);
}
}
void *th2(void *arg)
{
while (1)
{
printf("吃饭\n");
sleep(1);
}
}
int main(int argc, char **argv)
{
pthread_t tid1,tid2;
pthread_create(&tid1, NULL, th1, NULL);
pthread_create(&tid1, NULL, th2, NULL);
while (1)
{
sleep(1);
}
return 0;
}
2.获得线程tid号
#include
#include
#include
#include
#include
#include
void *th1(void *arg)
{
while (1)
{
printf("打瓦 th1, tid:%ld\n",pthread_self());
sleep(1);
}
}
void *th2(void *arg)
{
while (1)
{
printf("吃饭 th2, tid:%ld\n",pthread_self());
sleep(1);
}
}
int main(int argc, char **argv)
{
pthread_t tid1,tid2;
pthread_create(&tid1, NULL, th1, NULL);
pthread_create(&tid1, NULL, th2, NULL);
while (1)
{
printf("main th, tid:%ld\n",pthread_self());
sleep(1);
}
return 0;
}
3.strerror
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
int i = 0 ;
for(i=0;i<400;i++)
{
printf("%d %s\n",i,strerror(i));
}
//system("pause");
return 0;
}
4.线程的exit
#include
#include
#include
#include
#include
#include
#include
void *th(void *arg)
{
int i = 3;
while(i--)
{
printf("th,tid:%ld\n",pthread_self());
sleep(1);
}
pthread_exit(NULL);
}
int main(int argc, char **argv)
{
pthread_t tid;
pthread_create(&tid, NULL, th, NULL);
while (1)
{
sleep(1);
}
//system("pause");
return 0;
}
5.线程的cancel
#include
#include
#include
#include
#include
#include
#include
void *th(void *arg)
{
int i = 3;
while(i--)
{
printf("th,tid:%ld\n",pthread_self());
sleep(1);
}
pthread_exit(NULL);
}
int main(int argc, char **argv)
{
pthread_t tid;
pthread_create(&tid, NULL, th, NULL);
int i = 0;
while (1)
{
printf("main th, tid : %ld\n", pthread_self());
sleep(1);
++i;
if(3 == i)
{
pthread_cancel(tid);
}
}
//system("pause");
return 0;
}
6.线程的回收
#include
#include
#include
#include
#include
void *th(void *arg)
{
int i = 5;
while(i--)
{
printf("th tid:%ld\n", pthread_self());
sleep(1);
}
return NULL;
}
int main(int argc, char **argv)
{
pthread_t tid;
pthread_create(&tid, NULL, th, NULL);
pthread_join(tid, NULL);
return 0;
}
7.线程join带返回值
#include
#include
#include
#include
#include
void *th(void *arg)
{
char *p = (char *)malloc(50);
strcpy(p, "小凡是人机");
sleep(3);
return p;
}
int main(int argc, char **argv)
{
pthread_t tid;
pthread_create(&tid, NULL, th, NULL);
void *ret;
pthread_join(tid, &ret);
printf("ret %s\n",(char*)ret);
free(ret);
return 0;
}
8.线程的共享特性
#include
#include
#include
#include
#include
int a = 0;
void *th(void *arg)
{
sleep(1);
a += 10;
return NULL;
}
int main(int argc, char **argv)
{
pthread_t tid;
printf("a is %d\n", a);
pthread_create(&tid, NULL, th, NULL);
pthread_join(tid, NULL);
printf("a is %d\n", a);
return 0;
}
9.
#include
#include
#include
#include
#include
#include
typedef struct
{
char name[50];
int age;
char addr[50];
}PER;
void *th(void *arg)
{
PER *per = (PER*)arg;
printf("th: %s %d %s\n", per->name, per->age, per->addr);
strcat(per->name, "Runa");
return per;
}
int main(int argc, char **argv)
{
PER per;
bzero(&per, sizeof(per));
printf("input name:");
fgets(per.name, sizeof(per.name), stdin);
per.name[strlen(per.name) - 1] = '\0';
char buf[5] = {0};
printf("input age:");
fgets(buf, sizeof(buf), stdin);
per.age = atoi(buf);
printf("input addr:");
fgets(per.addr, sizeof(per.addr), stdin);
per.addr[strlen(per.addr) - 1] = '\0';
pthread_t tid;
pthread_create(&tid, NULL, th, &per);
void *ret = NULL;
pthread_join(tid, &ret);
printf("join ret: %s %d %s\n",per.name
, per.age, ((PER*)ret)->addr);
return 0;
}
10.线程的栈区自动回收
#include
#include
#include
#include
void* th(void* arg)
{
pthread_detach(pthread_self()); //栈区系统自动回收
return NULL;
}
int main(int argc, char** argv)
{
int i = 0;
pthread_t tid;
for (i = 0; i < 50000; i++)
{
int ret = pthread_create(&tid, NULL, th, NULL);
if (ret != 0)
{
break;
}
printf("%d\n", i);
}
system("pause");
return 0;
}
11.线程的清除
#include
#include
#include
#include
#include
void clean(void *arg)
{
printf("this clean %s\n", (char*)arg);
free(arg);
}
void* th(void* arg)
{
strcpy((char* )arg,"hello world\n");
printf("th,strcpy over\n");
return NULL;
}
int main(int argc, char **argv)
{
pthread_t tid;
char* p = malloc(50);
pthread_cleanup_push(clean,p);
pthread_create(&tid,NULL,th,p);
pthread_join(tid,NULL);
printf("before pop\n");
pthread_cleanup_pop(1);
system("pause");
return 0;
}