赞
踩
thread:这是一个指向pthread_t类型的指针,用于获取新创建线程的线程ID。在调用pthread_create后,这个指针会被设置为新线程的ID。
attr:这是一个指向pthread_attr_t类型的指针,用于设置线程的属性,如栈大小、优先级等。如果这个参数为NULL,那么线程将使用默认的属性。通常情况下,如果你不需要设置特殊的线程属性,可以传递NULL。
start_routine:这是一个函数指针,指向线程开始执行时要调用的函数。这个函数通常被称为线程的“入口点”或“启动例程”。
arg:用于向线程的启动例程传递参数。你可以通过这个参数向线程传递任何类型的数据。如果你的启动例程不需要任何参数,可以传递NULL。
终止线程的三种方法:
- 在线程函数的内部使用return语句。
- 在线程函数的内部使用pthread_exit函数。
- 在主线程中使用pthread_cancel函数,可以回收指定的子线程。
pthread_exit函数中可以设置retval返回值,在主线程中可以调用pthread_join函数来获取子线程的返回值。
在主线程中使用pthread_cancel函数,在pthread_cancel函数中传入子进程的id可以直接终止子线程,不用等子线程跑完。
不能用exit终止线程,因为exit是用来终止进程的,一旦exit执行了,那么整个进程也就退出了。
线程也要被等待回收,不然会出现类似于进程等待那里的僵尸问题,也就是出现内存泄漏。
pthread_join函数可以用来回收子线程,第一个参数为子线程的id, 第二个参数可以得到子线程的退出信息。主线程退出整个进程就跟着退出了,也就意味着主线程退出所有线程都要跟着退出,所以我们一般需要主线程最后退出来等待回收子线程。
下面由主线程创建一批子线程,分配给子线程任务,子线程将结果封装起来并返回给主线程,主线程由此可以获取子线程的执行结果。
对任务进行封装,让子线程去执行加法任务:
- class Task
- {
- private:
- int _x;
- int _y;
- public:
- Task(int x, int y)
- :_x(x), _y(y)
- {}
-
- int Add()
- {
- return _x + _y;
- }
- ~Task()
- {}
- };

分配给子线程任务,并回收结果:
- #include <iostream>
- #include <pthread.h>
- #include <unistd.h>
- #include <vector>
- using namespace std;
-
- class ThreadData
- {
- private:
- Task _t;
- string _name;
- public:
- ThreadData(Task t, string name)
- :_t(t), _name(name)
- {}
-
- Task getTask()
- {
- return _t;
- }
-
- string getName()
- {
- return _name;
- }
- ~ThreadData()
- {}
- };
- //结果封装
- class Res
- {
- private:
- int _result;
- string _name;
- public:
- Res(int result, string name)
- :_result(result)
- ,_name(name)
- {}
-
- int getResult()
- {
- return _result;
- }
-
- string getName()
- {
- return _name;
- }
- ~Res()
- {}
- };
- //子线程执行的函数
- void* handler(void* args)
- {
- ThreadData* th = (ThreadData*)args;
- Res* res = new Res(th->getTask().Add(), th->getName());
- delete th;
- return res;
- }
-
- vector<pthread_t> vect_tid;
- vector<Res*> vect_res;
- int main()
- {
- for(int i = 0; i<5; i++)
- {
- pthread_t tid;
- Task task(10, 20);
- char buffer[1024];
- snprintf(buffer, sizeof(buffer), "thread-%d", i+1);
- ThreadData* th = new ThreadData(task, buffer);
- pthread_create(&tid, nullptr, handler, th);
- vect_tid.push_back(tid);
- }
-
- for(auto& e : vect_tid)
- {
- void* ret = nullptr;
- pthread_join(e, &ret);
- vect_res.push_back((Res*)(ret));
- }
-
- for(auto& e : vect_res)
- {
- cout << e->getName() << " " << "res=" << e->getResult() << endl;
- delete e;
- }
- return 0;
- }

线程被创建出来的时候默认是joinable的,也就是说需要被等待的。如果我们的主线程并不关心新线程的执行结果,我们可以将新线程设置为分离状态。所谓的分离只是进程的一种工作状态,在底层依旧数据共享,依旧属于同一个进程。
- #include <iostream>
- #include <pthread.h>
- #include <unistd.h>
-
- void* handler(void* args)
- {
- const std::string str = static_cast<const char*> (args);
- int cnt = 5;
- while(cnt--)
- {
- std::cout << str << std::endl;
- sleep(1);
- }
-
- return nullptr;
- }
-
- int main()
- {
- pthread_t tid;
- pthread_create(&tid, nullptr, handler, (void*)"new Thread");
- //detach可以放在main函数中也可以放在handler函数中
- pthread_detach(tid);
- while(true)
- {}
- return 0;
- }

分离之后再主线程中就不需要再对子线程进行等待回收了,即不需要在主线程中调用pthread_join函数。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。