Linux系统编程-DAY06
一、线程概念
进程和线程共同点:并发
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 <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
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 <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>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 <stdio.h>
#include <bits/pthreadtypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
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 <stdio.h>
#include <bits/pthreadtypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <pthread.h>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 <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>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 <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
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;
}