多线程和互斥量

来源:互联网 发布:google翻译软件下载 编辑:程序博客网 时间:2024/06/01 07:40

在单核处理器上,内核使用时间分片来模拟线程的并发执行;在多核处理器上,线程与进程一样,可以并发执行。

两种软件运行模式:单进程/多线程模式,非多进程/单线程模式。为什么使用线程不使用进程?进程间通信(IPC)困难。每个进程拥有独自的内存空间,而线程共享相同的内存空间。http://blog.csdn.net/zmxiangde_88/article/details/7998458


Liunx线程基本函数

#include <pthread.h>

1.线程创建:

int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);

参数说明:

thread:指向pthread_create类型的指针,用于引用新创建的线程。

attr:用于设置线程的属性,一般不需要特殊的属性,所以可以简单地设置为NULL。

*(*start_routine)(void *):传递新线程所要执行的函数地址。

arg:新线程所要执行的函数的参数。

调用如果成功,则返回值是0,如果失败则返回错误代码。

2.线程终止

void pthread_exit(void *retval);

参数说明:

retval:返回指针,指向线程向要返回的某个对象。

线程通过调用pthread_exit函数终止执行,并返回一个指向某对象的指针。注意:绝不能用它返回一个指向局部变量的指针,因为线程调用该函数后,这个局部变量就不存在了,这将引起严重的程序漏洞。

3.线程同步

int pthread_join(pthread_t th, void **thread_return);

参数说明:

th:将要等待的线程。

thread_return:线程的返回值。


互斥体(mutex,mutual exclusion的缩写)。一个互斥体一次只允许一个线程访问共享区。当一个线程想要访问共享区时,首先要做的就是锁住(lock)互斥体。如果其他的线程已经锁住了互斥体,那么就必须先等那个线程将互斥体解锁,这样就保证了同一时刻只有一个线程能访问共享区域。

Boost线程库支持两大类互斥体,包括简单互斥体(simple mutex)和递归互斥体(recursive mutex)。如果同一个线程对互斥体上了两次锁,就会发生死锁(deadlock),也就是说所有的等待解锁的线程将一直等下去。有了递归互斥体,单个线程就可以对互斥体多次上锁,当然也必须解锁同样次数来保证其他线程可以对这个互斥体上锁。

在这两大类互斥体中,对于线程如何上锁还有多个变种。一个线程可以有三种方法来对一个互斥体加锁:

  1. 一直等到没有其他线程对互斥体加锁。
  2. 如果有其他互斥体已经对互斥体加锁就立即返回。
  3. 一直等到没有其他线程互斥体加锁,直到超时。
boost::mutex,
boost::try_mutex,
boost::timed_mutex,
boost::recursive_mutex,
boost::recursive_try_mutex,
boost::recursive_timed_mutex

  1. boost::mutex::scoped_lock lock(mutex_);  
  2. cond_.wait(lock);  
这两行代码,第一行锁定mutex_对象。第二行代码首先解开这个mutex_上的锁(为了其它线程能够使用该mutex_),然后进行等待,直到其它线程在该条件变量上调用notify_one()或者notify_all()函数。条件变量为真后,第二行代码尝试给mutex_上锁。
cond_.notify_all函数,通知那些所有正在等待cond_条件变量变为真的线程,那些线程随后进入运行状态。

fast_mutex.hpp中定义了跨平台的简单易用的互斥量。
代码来源于https://sourceforge.net/projects/nvwa/
#ifdef WIN32#define WIN32_LEAN_AND_MEAN#include <windows.h>class fast_mutex{private:    CRITICAL_SECTION _M_mtx_impl;public:    fast_mutex()    {        ::InitializeCriticalSection(&_M_mtx_impl);    }    ~fast_mutex()    {        ::DeleteCriticalSection(&_M_mtx_impl);    }    void lock()    {        ::EnterCriticalSection(&_M_mtx_impl);    }    bool trylock()    {        if (::TryEnterCriticalSection(&_M_mtx_impl)) {            return true;        }else{            return false;        }    }    void unlock()    {        ::LeaveCriticalSection(&_M_mtx_impl);    }private:    // 禁止拷贝构造函数和赋值构造函数    fast_mutex(const fast_mutex&);    fast_mutex& operator=(const fast_mutex&);};#else // for Linux#include <pthread.h>class fast_mutex{private:    pthread_mutex_t _M_mtx_impl;    pthread_mutexattr_t _M_mtx_attr;public:    fast_mutex()    {        ::pthread_mutexattr_init(&_M_mtx_attr);        ::pthread_mutexattr_settype(&_M_mtx_attr, PTHREAD_MUTEX_RECURSIVE);        ::pthread_mutex_init(&_M_mtx_impl, &_M_mtx_attr);    }    ~fast_mutex()    {        ::pthread_mutex_destroy(&_M_mtx_impl);        ::pthread_mutexattr_destroy(&_M_mtx_attr);    }    void lock()    {        ::pthread_mutex_lock(&_M_mtx_impl);    }    bool trylock()    {        if (::pthread_mutex_trylock(&_M_mtx_impl)) {            return true;        } else {            return false;        }    }    void unlock()    {        ::pthread_mutex_unlock(&_M_mtx_impl);    }private:    // 禁止拷贝构造函数和赋值构造函数    fast_mutex(const fast_mutex& );    fast_mutex& operator=(const fast_mutex&);};#endif // end for WIN32




0 0
原创粉丝点击