文章目录
- 九、多线程
- 2. 线程的控制
- 未完待续
九、多线程
2. 线程的控制
主线程退出 等同于 进程退出 等同于 所有线程都退出。为了避免主线程退出,但是新线程并没有执行完自己的任务的问题,主线程同样要跟进程一样等待新线程返回。
pthread_join 函数则可以等待新线程返回。
Makefile:
test_thread: testThread.cc
g++ -o $@ $^ -std=c++11 -lpthread
.PHONY: clean
clean:
rm -f test_thread
testThread.cc:
#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;
// 新线程
void* newpthreadrun(void* arg)
{
int cnt = 5;
while (cnt--)
{
cout << "I am newpthreadrun thread" << endl;
sleep(1);
}
}
int main()
{
pthread_t tid;
pthread_create(&tid, nullptr, newpthreadrun, nullptr);
// 主线程
pthread_join(tid, nullptr);
cout << "I am main thread" << endl;
sleep(5);
return 0;
}
多线程中,任何一个线程出现异常,都会导致整个进程退出 ---- 多线程代码往往健壮性不好。 不能用 exit() 来退出线程,因为 exit() 是退出进程的,可以使用 pthread_exit() 来退出线程,也可以在主线程中使用 pthread_cancel() 来取消新线程线程,新线程会返回 -1。
我们来创建一个多线程:
Makefile:
test_thread: testThread.cc
g++ -o $@ $^ -std=c++11 -lpthread
.PHONY: clean
clean:
rm -f test_thread
testThread.cc:
#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int threadnum = 5;
// 加法任务
class Task
{
public:
Task(int x, int y)
:datax(x)
,datay(y)
{}
int Excute()
{
return datax + datay;
}
~Task() {}
private:
int datax;
int datay;
};
// 线程数据
class ThreadData
{
public:
ThreadData(int x, int y, const string& threadname)
:t(x, y)
,threadname(threadname)
{}
string Threadname()
{
return threadname;
}
int run()
{
return t.Excute();
}
~ThreadData() {}
private:
string threadname;
Task t;
};
// 执行任务后的结果
class Result
{
public:
Result() {}
void SetResult(int result, const string& threadname)
{
_result = result;
_threadname = threadname;
}
void Print()
{
cout << _threadname << " run result: " << _result << endl;
}
~Result() {}
private:
int _result;
string _threadname;
};
// 线程执行任务
void* handlerTask(void* args)
{
ThreadData* td = static_cast<ThreadData*>(args);
string name = td->Threadname();
Result* res = new Result();
int result = td->run();
res->SetResult(result, name);
return res;
}
int main()
{
// 创建线程并分配任务
vector<pthread_t> threads;
for (int i = 0; i < threadnum; i++)
{
char threadname[64];
snprintf(threadname, 64, "Thread-%d", i + 1);
ThreadData* td = new ThreadData(10, 20, threadname);
pthread_t tid;
pthread_create(&tid, nullptr, handlerTask, td);
threads.push_back(tid);
}
// 等待线程执行完毕并获取结果
vector<Result*> result_set;
void* ret = nullptr;
for (auto& tid : threads)
{
pthread_join(tid, &ret);
result_set.push_back((Result*)(ret));
}
// 打印结果
for (auto& res : result_set)
{
res->Print();
delete res;
}
return 0;
}
执行结果: