linux 线程相关api,Linux原生线程API

Linux 下的多线程遵循POSIX标准,叫做pthread。编写Linux下的线程时,需要包含pthread.h头文件,在生成可执行文件时候需要链接libpthread.a或者libpthread.so

1.Linux下线程创建pthread_create()

#include

int pthread_create(

pthread_t *thread, //用于标识一个线程

pthread_attr_t *attr, // 用于设置线程的属性,如果为NULL ,则是默认属性

void *(*start_routine)(void *),// 当线程的资源分配成功后,线程中运行的单元。通常为一个函数

void *arg //线程函数运行时传入参数()

);

创建成功返回0;若不为零则线程创建失败

2.线程的结束函数pthread_join()和pthread_exit()

函数pthread_join()用来等待一个线程运行结束。这个函数是个阻塞函数,一直被等待的线程结束为止,函数才返回并且回收被等待线程的。

函数原型

extern int pthread_join __P((pthread_t __th,void **__thread_return));

//__th :线程标识符,就是pthread_create();//创建成功的值

//__thread_return ;:线程返回值,它是一个指针,用来存储被等待线程的值。

线程退出

extern void  pthread_exit   __p((void  *__retval ))

3.线程其他API

设置线程为分离态:

int pthread_detach (pthread_t __th);

获取线程自己:

pthread_t pthread_self (void)

终止线程:

int pthread_cancel(pthread_t thread):

线程可以通过调用pthread_cancel函数来请求取消同一进程中的其线程。发送终止信号给thread线程,如果成功则返回0,否则为非0值。发送成功并不意味着thread会终止。注意pthread_cancel并不等待线程终止,它仅仅提出请求。

比较线程

int pthread_equal(pthread_t tid1, pthread_t tid2);

返回值: 相等返回非0, 不相等返回0.

说明: 比较两个线程ID是否相等.

4.线程的属性:pthread_attr_t

从上例中,用pthread_create() 函数创建线程时,使用了默认参数,将第二个参数设置为NULL,建立一个线程时候,使用默认属性就够了,但很多时候需要调整线程的属性,特别是线程的优先级;

typedef struct _pthread_attr_s{

int _detachstate; /*线程终止状态*/

int _schedpolicy; /*调度优先级*/

struct _sched_param _schedparam; /*参数*/

int _inheritsched; /*继承*/

int _scope; /*范围*/

size_t _guardsize; /*保证尺寸*/

int _stackaddr_set; /*运行栈*/

void *_stackaddr; /**线程运行栈的大小*/

size_t _stacksize; /**线程运行栈大小*/

}pthread_attr_t;

1)      线程的优先级

由两个优先级设置

函数:pthread_attr_getschedparam();获得线程的优先级

函数:pthread_attr_setschedparam();设置线程的优先级

//设置线程优先级

int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);

//获取线程优先级

int pthread_attr_getschedparam(const pthread_attr_t *attr, struct schedparam *param);

线程的优先级存放在数据结构sched_param中(包含在sched.h中),操作方式是将优先级取出来,然后对需要设置的参数修改后再写回去。

例子如下:

#include

#include

#include

pthread_attr_t attr;

struct sched_param sch;

pthread_t pt;

pthread_attr_init(&attr);

/*获得当前线程属性**/

pthread_attr_getschedparam(&attr,&sch);

sch.sched_priority=256; /**设置优先级为256****/

pthread_attr_setschedparam(&attr,&sch); /**设置线程优先级**/

/**建立线程****/

pthread_create(&pt,&attr,(void *)start_rountin,&run);

/*****属性销毁***/

int pthread_attr_destroy(pthread_attr_t *attr);

5.线程互斥

互斥锁是用来保护一段临界区的,它可以保证某段时间内只有一个线程在执行一段代码或者访问 某个资源。

1.线程互斥的函数介绍:

#include

pthread_mutex_t mutex; /*互斥区**/

/*互斥锁初始化*/

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

/****锁定互斥***/

int pthread_mutex_lock(pthread_mutex_t *mutex);

/*****互斥预锁定******/

int pthread_mutex_trylock(pthread_mutex_t mutex);

/***解锁互斥*******/

int pthread_mutex_unlock(pthread_mutex_t *mutex);

/****销毁互斥锁*******/

Int pthread_mutex_destroy(pthread_mutex_t *mutex);

6.条件变量

互斥锁和条件变量的属性

在前面的互斥锁和条件变量的讲解中,我们用两个常量PTHREAD_MUTEX_INITIALIZER和PTHREAD_COND_INITIALIZER来初始化它们。有这种方式初始化的互斥锁和条件变量具备默认属性,不过我们还能以非默认属性来初始化它们。

#include

//互斥锁代码初始化

int pthread_mutex_init(pthread_mutex_t *mptr,const pthread_mutex_mutexattr_t *attr);

int pthread_mutex_destory(pthread_mutex_t *mptr);

//条件变量代码初始化

int pthread_cond_init(pthread_cond_t *cptr,const pthread_cond_condattr_t *attr);

int pthread_cond_destory(pthread_cond_t *cptr);

条件变量(Condition):等待与信号发送

互斥锁用于上锁,条件变量用于等待。这两种不同类型的同步都是需要的。

条件变量是类型为pthread_cond_t的变量,以下两个函数使用了这些变量:

#include

int pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr);

int pthread_cond_signal(pthread_cond_t *cptr);

//均返回:若成功则为0,若出错则为正的Exxx值

条件变量:定时等待和广播

通常pthread_cond_signal只唤醒等待在相应条件变量上的一个线程。在某些情况下,一个线程认定有多个其他线程应被唤醒,这时它可以调用pthread_cond_broadcast唤醒阻塞在相应条件变量上的所有线程。

#include

int pthread_cond_broadcast(pthread_cond_t *cptr);

int pthread_cond_timewait(pthread_cond_t *cptr,pthread_mutex_t *mptr,const struct timespc *abstime);

对于pthread_cond_timewait(...),其允许线程就阻塞时间设置一个限制值。Abstime参数是一个timespec结构体,该结构体指定这个函数必须返回的时间,即便当时相应的条件变量还没收到信号,如果发生这种超时情况,该函数返回ETIMEDOUT错误。该时间值是绝对时间。而不是时间差。

7.Linux 的多线程编程案例

Linux 出租车案例代码实例

#include

// 提示出租车到达的条件变量

pthread_cond_t taxiCond;

// 同步锁

pthread_mutex_t taxiMutex;

// 旅客人数,初始为 0

int travelerCount=0;

// 旅客到达等待出租车

void * traveler_arrive(void * name) {

cout<< ” Traveler: ” <

pthread_mutex_lock(&taxiMutex);

// 提示旅客人数增加

travelerCount++;

pthread_cond_wait (&taxiCond, &taxiMutex);

pthread_mutex_unlock (&taxiMutex);

cout<< ” Traveler: ” << (char *)name << ” now got a taxi! ” <

pthread_exit( (void *)0 );

}

// 出租车到达

void * taxi_arrive(void *name)

{

cout<< ” Taxi ” <

{

pthread_mutex_lock(&taxiMutex);

// 当发现已经有旅客在等待时,才触发条件变量

if(travelerCount>0)

{

pthread_cond_signal(&taxtCond);

pthread_mutex_unlock (&taxiMutex);

break;

}

pthread_mutex_unlock (&taxiMutex);

}

pthread_exit( (void *)0 );

}

void main() {

// 初始化

taxtCond= PTHREAD_COND_INITIALIZER;

taxtMutex= PTHREAD_MUTEX_INITIALIZER;

pthread_t thread;

pthread_attr_t threadAttr;

pthread_attr_init(&threadAttr);

pthread_create(&thread, & threadAttr, taxt_arrive, (void *)( ” Jack ” ));

sleep(1);

pthread_create(&thread, &threadAttr, traveler_arrive, (void *)( ” Susan ” ));

sleep(1);

pthread_create(&thread, &threadAttr, taxi_arrive, (void *)( ” Mike ” ));

sleep(1);

return 0;

}

8.互斥锁封装

摘自libprocess源代码:

Synchronized.h

#include

class Synchronizable

{

public:

Synchronizable()

: initialized(false) {}

explicit Synchronizable(int _type)

: type(_type), initialized(false)

{

initialize();

}

Synchronizable(const Synchronizable &that)

{

type = that.type;

initialize();

}

Synchronizable & operator = (const Synchronizable &that)

{

type = that.type;

initialize();

return *this;

}

void acquire()

{

if (!initialized) {

}

pthread_mutex_lock(&mutex);

}

void release()

{

if (!initialized) {

}

pthread_mutex_unlock(&mutex);

}

private:

void initialize()

{

if (!initialized) {

pthread_mutexattr_t attr;

pthread_mutexattr_init(&attr);

pthread_mutexattr_settype(&attr, type);

pthread_mutex_init(&mutex, &attr);

pthread_mutexattr_destroy(&attr);

initialized = true;

} else {

}

}

int type;

bool initialized;

pthread_mutex_t mutex;

};

class Synchronized

{

public:

explicit Synchronized(Synchronizable *_synchronizable)

: synchronizable(_synchronizable)

{

synchronizable->acquire();

}

~Synchronized()

{

synchronizable->release();

}

operator bool () { return true; }

private:

Synchronizable *synchronizable;

};

#define synchronized(s) \

if (Synchronized __synchronized ## s = Synchronized(&__synchronizable_ ## s))

#define synchronizable(s) \

Synchronizable __synchronizable_ ## s

#define synchronizer(s) \

(__synchronizable_ ## s)

#define SYNCHRONIZED_INITIALIZER Synchronizable(PTHREAD_MUTEX_NORMAL)

#define SYNCHRONIZED_INITIALIZER_DEBUG Synchronizable(PTHREAD_MUTEX_ERRORCHECK)

#define SYNCHRONIZED_INITIALIZER_RECURSIVE Synchronizable(PTHREAD_MUTEX_RECURSIVE)

使用方法:

#include

#include

#include

using namespace std;

#include

#include "Synchronized.h"

string generate(const string& prefix)

{

static map* prefixes = new map();

static synchronizable(prefixes) = SYNCHRONIZED_INITIALIZER;//初始化

int id;

synchronized (prefixes) {

int& _id = (*prefixes)[prefix];

_id += 1;

id = _id;

}

printf("%d\n", id);

return prefix + "(" + ")";

}

int main()

{

printf("%s\n", generate("heihei").c_str());

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值