join()的作用前面已经提到,主线程等待子线程结束方可执行下一步(串行),detach()是的子线程放飞自我,独立于主线程并发执行,主线程后续代码段无需等待。看看效果:
#include <thread>
#include <iostream>
#include <mutex>
void hello_thread(){
std::cout<<"hello Thread1"<<std::endl;
}
int main(){
std::thread t1(hello_thread);
t1.join();
std::cout<< "main thread" <<std::endl;
getchar();
return 0;
}
编译命令:
gcc demo1.cpp -lstdc++ -o demo1 -lpthread
可时启多个线程 ,简单例子
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#define NUM 10
int count;
void* thread_func(void *arg){
count++;
// printf("count %d\n" , count);
sleep(20);
printf("count %d\n" , count);
return 0;
}
int main()
{
pthread_t tid[NUM];
int i=0;
for(int i=0;i<NUM;i++)
{
pthread_create(&tid[i],NULL,thread_func,NULL);
}
sleep(5);
printf("main thread\n");
return 0;
}
在类内部启动线程
#include <thread>
#include <iostream>
#include <mutex>
class HelloThread{
public:
static void hellothread(){
std::cout<<"Hello world,i''m a thread!"<<std::endl;
}
static void start(){
std::thread thrd(hellothread);
thrd.join();
}
};
int main()
{
HelloThread::start();
getchar();
return 0;
}
用类内部函数在类外部创建线程
非常普通的类,只是用多线程调用其内部的函数
#include <thread>
#include <iostream>
#include <mutex>
#include <functional>
class HelloWorld{
public:
void hello(int year){
std::cout<<"year="<<year<<std::endl;
}
};
int main(int args,char* argv[])
{
HelloWorld obj;
std::thread thrd(std::bind(&HelloWorld::hello,&obj,88));
thrd.join();
getchar();
return 0;
}
数据同步最简单的例 子
#include <thread>
#include <iostream>
#include <mutex>
#include <functional>
std::mutex mt;
int data=1;
void add(int a=1){
mt.lock();
data=data+a;
std::cout<<"add after data="<<data<<std::endl;
mt.unlock();
}
void multi(int b=2){
mt.lock();
data=data*b;
std::cout<<"multi after data="<<data<<std::endl;
mt.unlock();
}
int main(){
std::thread t1(add,44);
std::thread t2(multi,10);
t1.detach();
t2.detach();
getchar();
return 0;
}
GCC 编译命令
一. 常用编译命令选项
假设源程序文件名为test.c。
1. 无选项编译链接
用法:#gcc test.c
作用:将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件,默认输出为a.out。
2. 选项 -o
用法:#gcc test.c -o test
作用:将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名。
3. 选项 -E
用法:#gcc -E test.c -o test.i
作用:将test.c预处理输出test.i文件。
4. 选项 -S
用法:#gcc -S test.i
作用:将预处理输出文件test.i汇编成test.s文件。
5. 选项 -c
用法:#gcc -c test.s
作用:将汇编输出文件test.s编译输出test.o文件。
6. 无选项链接
用法:#gcc test.o -o test
作用:将编译输出文件test.o链接成最终可执行文件test。
7. 选项-O
用法:#gcc -O1 test.c -o test
作用:使用编译优化级别1编译程序。级别为1~3,级别越大优化效果越好,但编译时间越长。
二. 多源文件的编译方法
如果有多个源文件,基本上有两种编译方法:
[假设有两个源文件为test.c和testfun.c]
1. 多个文件一起编译
用法:#gcc testfun.c test.c -o test
作用:将testfun.c和test.c分别编译后链接成test可执行文件。
2. 分别编译各个源文件,之后对编译后输出的目标文件链接。
用法:
#gcc -c testfun.c //将testfun.c编译成testfun.o
#gcc -c test.c //将test.c编译成test.o
#gcc -o testfun.o test.o -o test //将testfun.o和test.o链接成test
以上两种方法相比较,第一中方法编译时需要所有文件重新编译,而第二种方法可以只重新编译修改的文件,未修改的文件不用重新编译。
编译时指定include
gcc –c –I /usr/dev/mysql/include test.c –o test.o
编译时指定include ,-I
gcc –c –I /usr/dev/mysql/include test.c –o test.o
编译时指定连接库-L
gcc –L /usr/dev/mysql/lib –lmysqlclient test.o –o test
Linux下的库文件分为两大类分别是动态链接库(通常以.so结尾)和静态链接库(通常以.a结尾),
二者的区别仅在于程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。
静态库链接时搜索路径顺序:
1. ld会去找GCC命令中的参数-L
2. 再找gcc的环境变量LIBRARY_PATH
3. 再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的
动态链接时、执行时搜索路径顺序:
1. 编译目标代码时指定的动态库搜索路径
2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径
3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径
4. 默认的动态库搜索路径/lib
5. 默认的动态库搜索路径/usr/lib
有关环境变量:
LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径
LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径