项目中多线程的使用

来源:互联网 发布:零点网络 编辑:程序博客网 时间:2024/05/16 11:58

如下两篇文章对Linux 多线程讲的比较深入,详细:

Linux pthread详解

http://blog.csdn.net/xueye3000/article/details/7024365

Linux Pthread 深入解析

http://blog.chinaunix.net/uid-21084809-id-2215376.html

 

1. 项目中需要用到多线程, 为了使用的方便,将线程进行了封装,将Thread封装成一个接口类。virtual void* Run() = 0; 为纯虚函数。static void* Run(void*);为静态函数。

2. Thread 类继承了NoCopy(详见c/c++复制控制)。实现Thread对象不可被赋值,不可复制。

 

 线程的创建过程:

每个要创建线程的任务都会有一个Thread * m_thr;这样的数据成员。这些任务:

MBusMac.cc: Thread * m_thr;

TransInterface:  Thread* m_pPollThr;
                                  Thread* m_pConnThr;

 

网络连接线程的创建

 new CommLink(newsock);

class CommLink : public Thread 继承线程Thread

CommLink 的构造函数中,CommLink(int sock) : Thread(65536), d_sock(sock)  此处在Thread的构造函数中

线程属性初始化

pthread_attr_init(&d_attr);初始化了线程属性。设置了线程栈

pthread_attr_setstacksize(&d_attr, stacksize); stacksize为65535。

pthread_attr_setinheritsched(&d_attr, PTHREAD_INHERIT_SCHED);  //继承主线程的属性

 

线程启动
m_comm->Start(); 调用了Thread中的start函数,在其中创建了线程:

!d_started && pthread_create(&d_thread, &d_attr, Run, this) == 0

pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);  // 设置收到取消信号后立即退出,如果

是PTHREAD_CANCEL_DEFFERED延时取消,则运行到下一取消点时退出

在Run里面调用派生类的Run()。从而启动了一个线程。

 

线程退出

在线程退出后,调用pthread_cleanup_pop(1);(前面必须有pthread_cleanup_push(Cleanup, p);)。 然后Cleanup会对线程做清理工作。delete this;。

然后会调用:

Thread::~Thread()
{
 if (d_started)
  pthread_detach(d_thread);
 pthread_attr_destroy(&d_attr);
}
将线程设为分离状态,销毁属性。

 

Thread::Wait() 中封装了join函数

pthread_join()函数,以阻塞的方式等待thread指定的线程结束。当函数返回时,被等待线程的资源被收回。如果进程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable的。
 
可以通过pthread_join()函数来使主线程阻塞等待其他线程退出,这样主线程可以清理其他线程的环境。但是还有一些线程,更喜欢自己来清理退出的状态,他们也不愿意主线程调用pthread_join来等待他们。我们将这一类线程的属性称为detached。
 
理论上说,pthread_exit()和线程宿体函数退出的功能是相同的,函数结束时会在内部自动调用pthread_exit()来清理线程相关的资源。但实际上二者由于编译器的处理有很大的不同。  
进程主函数(main())中调用pthread_exit(),只会使主函数所在的线程(可以说是进程的主线程)退出;而如果是return,编译器将使其调用进程退出的代码(如_exit()),从而导致进程及其所有线程结束运行。