#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <pthread.h> // pthread头文件
#include <unistd.h> // sleep的头文件
using namespace std;
// 两个线程
pthread_t thread1;
pthread_t thread2;
// 线程里会调用的函数
void *fn(void *arg)
{
int i = *(int *)arg;
cout<<"i = "<<i<<endl;
for(int j = 0; j < i; j++)
{
cout <<"i = " << i <<",j = " << j << endl;
sleep(0.5);
}
return ((void *)0);
}
int main()
{
// 随便定义的两个临时变量
int i1 = 3;
int i2 = 10;
// 创建第一个线程。创建之后线程立即就执行,不需要什么触发、调用,因为它是线程,不是函数
pthread_create(&thread1, NULL, &fn, &i1);
cout << "Half 0!" << endl;
// 创建第二个线程。第二个线程也立即执行。所以到此时,两个线程都在执行
pthread_create(&thread2, NULL, &fn, &i2);
// 阻塞主进程,等待第一个线程,第一个线程不结束,main函数不能返回
pthread_join(thread1, NULL);
cout << "Half!" << endl;
// 阻塞主进程,等待第二个线程,第二个线程不结束,main函数不能返回
// 如果此时第二个线程已经结束了,这个函数就马上返回
pthread_join(thread2, NULL);
cout << "Done!" << endl;
return 0;
}
注意:pthread的库不是Linux默认的库,所以链接的时候要手动链接,不然会报找不到符号的错误。
手动链接的方法就是加上-lpthread
执行的结果如下:
从打印的结果可以看到,pthread_creat()时调用之后马上就返回的,所以“Half 0”才能最先打印出来。pthread_creat()是不用等到它创建的那个线程执行完之后再返回的,不然就不能称之为异步了。等“Half 0”打印完之后,新线程thread1也开始打印了,这说明这时候thread1也开始工作了,现在是主进程和新线程thread1同时存在。
thread1起来后,先打印"i = 10",然后在循环里打印第一句“i = 10,j = 0”,然后thread2线程就起来了,开始打印"i = 3".在这之后两个线程加上主进程3个同时进行,打印结果里交替出现"i = 3"和"i = 10". 在两个线程进行打印的同时,主进程也进行到了第一个thread_join()这一步。这是一个阻塞函数,它不会马上返回,它要等到thread1进程结束以后才能返回。
由于3比10小,thread1比thread2先结束。这之后是thread2和主进程两个同时存在。thread1线程结束之后,第一个pthread_join()马上返回,然后主进程执行打印half的操作,然后执行第二个pthread_join().这个函数又必须等到thread2结束才能返回。
如果我们修改i1和i2的值,可以让这时候的thread2已经结束,如果这样的话,第二个pthread_join()就此时马上返回。当然,这不是我们这个例子的情况。
第二个pthread_join()返回后打印Done,然后main()结束。