目录
一、概念
二、理解
三、创建、退出、合并进程
//man pthread_create
//Compile and link with -pthread.
//1.为什么没有fun函数?
//2.加上sleep来改进
//3.线程结束会不会影响主线程运行?
//4.那如果主线程比较少呢?
四、如何解决主线程比子线程早结束,子线程不执行问题?
调用等待线程:pthread_join();
五、退出程序
pthread_exit();
一、概念
进程:一个正在运行的程序;
线程:进程内部的一条执行路径(序列)
目的:理解并发运行、知道如何同步、知道线程安全概念
并发:在一段时间内,两条交替运行,只有一个处理器
并行:两条路径一直在执行,单个处理器无法满足,需要多个处理器,有多个处理器也不一定是并行(要共享,不一定能独占)
二、理解
//只有唯一一条执行路径;
//有三条执行路径(三个线程可以做同一件事,也可做三件事)
三、创建、退出、合并进程
pthread_create()//创建线程
pthread_exit()//退出线程
pthread_join()//等待线程结束/合并线程
//man pthread_create
//线程ID、线程的属性(如果不设置,就给空指针)、线程函数(函数指针)、线程函数的参数(不传给空)
//main.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
void* fun(void* arg)
{
for(int i=0;i<5;i++)
{
printf("fun run\n");
}
}
int main()
{
pthread_t id;
pthread_create(&id,NULL,fun,NULL);
for(int i=0;i<5;i++)
{
printf("main run\n");
}
}
//此时我们直接运行,发现出错了
//Compile and link with -pthread.
所以 我们现在要指定线程库(-l指定库)
//1.为什么没有fun函数?
因为主函数一旦运行完了,在最后执行力exit,这个exit会退出整个进程,若此时线程还没有来得及往屏幕上打印,那么它就再也没有打印的机会了,整个进程退出了,线程没有运行完不等
//2.加上sleep来改进
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
void* fun(void* arg)
{
for(int i=0;i<5;i++)
{
printf("fun run\n");
sleep(1);
}
}
int main()
{
pthread_t id;
pthread_create(&id,NULL,fun,NULL);
for(int i=0;i<5;i++)
{
printf("main run\n");
sleep(1);
}
}
//运行结果
//main函数和fun函数同时交替进行(结果不一定是这个顺序)
//3.线程结束会不会影响主线程运行?
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
void* fun(void* arg)
{
for(int i=0;i<2;i++)
{
printf("fun run\n");
sleep(1);
}
}
int main()
{
pthread_t id;
pthread_create(&id,NULL,fun,NULL);
for(int i=0;i<5;i++)
{
printf("main run\n");
sleep(1);
}
exit(0);
}
//两个fun打印完了之后没有打印的main还在继续打印
//4.那如果主线程比较少呢?
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
void* fun(void* arg)
{
for(int i=0;i<7;i++)
{
printf("fun run\n");
sleep(1);
}
}
int main()
{
pthread_t id;
pthread_create(&id,NULL,fun,NULL);
for(int i=0;i<2;i++)
{
printf("main run\n");
sleep(1);
}
exit(0);
}
//本来主线程的结束跟子线程的结束没有必然的关系,但是主线程中有exit(0),会退出进程,就算不写exit,系统也会自动调用。
四、如何解决主线程比子线程早结束,子线程不执行问题?
调用等待线程:pthread_join();
// 线程参数、二级指针(接受线程反馈给主线程的信息,不接收的话给空)
clude<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
void* fun(void* arg)
{
for(int i=0;i<7;i++)
{
printf("fun run\n");
sleep(1);
}
}
int main()
{
pthread_t id;
pthread_create(&id,NULL,fun,NULL);
for(int i=0;i<2;i++)
{
printf("main run\n");
sleep(1);
}
pthread_join(id,NULL);
exit(0);
}
~
//main程序两次执行完了,还在执行fun函数,直至fun函数结束,join才会返回。
五、退出程序
pthread_exit();
//二级指针 (返回值不能是临时变量,可以为全局变量或者字符串常量,如果是临时空间,被销毁了就无法使用了)
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
void* fun(void* arg)
{
for(int i=0;i<7;i++)
{
printf("fun run\n");
sleep(1);
}
pthread_exit("fun over");
}
int main()
{
pthread_t id;
pthread_create(&id,NULL,fun,NULL);
for(int i=0;i<2;i++)
{
printf("main run\n");
sleep(1);
}
char* s=NULL;
pthread_join(id,(void**)&s);//传指针的地址会让s去指向fun over,接受线程反馈的指
printf("s=%s\n",s);
exit(0);
}
//执行结果,字符串s来源于线程返回给主线程