3、Linux多线程,线程同步

 

5)线程私有数据

    进程内的所有线程共享进程的数据空间,因此全局变量为所有线程所共有。但有时线程也需要保存自己的私有数据,这时可以创建线程私有数据(Thread-specific DateTSD来解决。在线程内部,私有数据可以被各个函数访问,但对其他线程是屏蔽的。例如我们常见的变量errno,它返回标准的出错信息。它显然不能是一个局部变量,几乎每个函数都应该可以调用它;但它又不能是一个全局变量,否则在A线程里输出的很可能是B线程的出错信息。要实现诸如此类的变量,我们就必须使用线程数据。我们为每个线程数据创建一个键,它和这个键相关联,在各个线程里,都使用这个键来指代线程数据,但在不同的线程里,这个键代表的数据是不同的,在同一个线程里,它代表同样的数据内容。

    线程私有数据采用了一键多值的技术,即一个键对应多个数值,访问数据时好像是对同一个变量进行访问,但其实是在访问不同的数据。

    创建私有数据的函数有4个:pthread_key_create(创建), pthread_setspecific(设置), pthread_getspecific(获取), pthread_key_delete(删除)

#include <pthread.h>

int pthread_key_creadte(pthread_key_t *key,void (*destr_fuction) (void *));

int pthread_setspecific(pthread_key_t key,const void * pointer));

void * pthread_getspecific(pthread_key_t key);

int pthread_key_delete(ptherad_key_t key);

6)线程同步

    线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点。linux下提供了多种方式来处理线程同步,最常用的是互斥锁、条件变量和异步信号。

1)互斥锁(mutex

    通过锁机制实现线程间的同步。同一时刻只允许一个线程执行一个关键部分的代码。

int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr);

int pthread_mutex_lock(pthread_mutex *mutex);

int pthread_mutex_destroy(pthread_mutex *mutex);

int pthread_mutex_unlock(pthread_mutex *

(1)先初始化锁init()或静态赋值pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIER

attr_t有:

PTHREAD_MUTEX_TIMED_NP:其余线程等待队列

PTHREAD_MUTEX_RECURSIVE_NP:嵌套锁,允许线程多次加锁,不同线程,解锁后重新竞争

PTHREAD_MUTEX_ERRORCHECK_NP:检错,与一同,线程请求已用锁,返回EDEADLK;

PTHREAD_MUTEX_ADAPTIVE_NP:适应锁,解锁后重新竞争

(2)加锁,lock,trylock,lock阻塞等待锁,trylock立即返回EBUSY

(3)解锁,unlock需满足是加锁状态,且由加锁线程解锁

(4)清除锁,destroy(此时锁必需unlock,否则返回EBUSY,//Linux下互斥锁不占用内存资源

示例代码

#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <pthread.h>
#include "iostream"
 
using namespace std;
 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int tmp;
 
void* thread(void *arg)
{
    cout << "thread id is " << pthread_self() << endl;
    pthread_mutex_lock(&mutex);
    tmp = 12;
    cout << "Now a is " << tmp << endl;
    pthread_mutex_unlock(&mutex);
    return NULL;   
}
 
int main()
{
    pthread_t id;
    cout << "main thread id is " << pthread_self() << endl;
    tmp = 3;
    cout << "In main func tmp = " << tmp << endl;
    if (!pthread_create(&id, NULL, thread, NULL))
    {
        cout << "Create thread success!" << endl;
    }
    else
    {
        cout << "Create thread failed!" << endl;
    }
    pthread_join(id, NULL);
    pthread_mutex_destroy(&mutex);
    return 0;
}

 

编译: g++ -o thread testthread.cpp -lpthread

说明:pthread库不是Linux系统默认的库,连接时需要使用静态库libpthread.a,所以在使用pthread_create()创建线程,以及调用pthread_atfork()函数建立fork处理程序时,需要链接该库。在编译中要加 -lpthread参数。

posted on 2013-01-17 13:29  一个人的天空@  阅读(304)  评论(0编辑  收藏  举报