pthread 入门

pthread 为POSIX线程库,windows和linux皆可用。
//例子来源教材,百度文库,以及csdn blog
1. 路径为/lib/x86_64-linux-gnu/, libpthread-2.15.so
这里写图片描述
这些lib 有不同的颜色。颜色的区别是什么?
libpci.so.3.1.8 和libpci.so.3 的区别是什么?
这里写图片描述
颜色不同,代表文件类型不同。用ll 查看。

-代表普通文件,白色
l代表软链接文件,蓝色
 还有绿色,代表具有可执行权限

关于蓝色软链接,以及lib*.so.*后面的数字,代表版本号。
当安装软件时,如果安装了这些同类库,但是版本不同,如果高版本可以兼容旧版本,则创建一个旧版本的软链接 ,不再创建新文件。
2. 线程的概念
线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。
一个进程是一个复合的实体,可以分为两个部分:线程集合 + 资源集合。
使用多线程一般有两个不同的目的:
一是把程序细分成几个功能相对独立的模块,防止其中一个功能模块阻塞导致整个程序假死(GUI程序是典型)(多任务
另一个就是提高运行效率,比如多个核同时跑,或者单核里面,某个线程进行IO操作时,另一个线程可以同时执行(并发)。
posix pthread 库

// 创建线程
#include <pthread.h>
int pthreat_t pthread_creat(pthread_t *thread,pthread_attr_t * attr,void *(*start_routine)(void *),void *arg)
//typedef unsigned long int pthread_t
//void * arg 用来向*start_routine 传参
//pthread_attr_t attr 指定线程属性,可以默认为NULL
//执行成功返回0,失败返回非零值。

//获得线程id
pthread_t pthread_self(); //无线,线程内部使用
//退出
    1 调用函数执行结束后自动退出
    2 使用函数退出
    void pthread_exit(void* retval) // 在想中途退出时,有用。成功返回0,失败-1。 返回值保存在retval 指针中。

demo1.cpp

#include <iostream>
#include <pthread.h>

using namespace std;
#define NUM_THREADS 5

void* say_hello(void* args)
{
    cout << "___HELLO___ "<< endl;
    pthread_exit(0);
}

int main()
{
    pthread_t tids[NUM_THREADS];
    for(int i = 0; i < NUM_THREADS; i++)
    {
    int ret = pthread_create(&tids[i],NULL,say_hello,(void *)&i);
    if(ret != 0)
        {
        cout << "Pthread create error !!!!"<< i <<"____"<< ret << endl;
        }

    else
    {
        cout << "main___"<< endl;
    }
}
    pthread_exit(NULL);////等各个线程退出后,进程才结束,否则进程强制结束了,线程可能还没反应过
来;
}
// g++ -o 1 1.cpp -lpthread   #此处-l指定库要放在后面,放在-o前面,会说ld 链接错误!! gcc g++ 这是个使用细节。

运行结果:

main___
main___
main___
main___
main___
___HELLO___ 
___HELLO___ 
___HELLO___ 
___HELLO___ 
___HELLO___ 

————————结果表明,主线程运行的速度远远比线程速度快多了。并且新线程和主线程是并发的。
demo2.c

#include <pthread.h>
#include <stdio.h>

void print_msg(char *ptr)
{
    int retval;
    printf("Thread_id is %lx______%s\n",pthread_self(),ptr);
    pthread_exit(&retval);
}
/*或者
void print_msg(void *ptr)
{
    int retval;
    printf("Thread_id is %lx______%s\n",pthread_self(),(char*)ptr);
    pthread_exit(&retval);
}
*/
int main()
{
    pthread_t thread1,thread2;
    char* msg1= "Hello ";
    char* msg2 = "WORLD ";
    printf("Let's go    \n");
    pthread_create(&thread1,NULL,(void*)(&print_msg),(void *)msg1);
    pthread_create(&thread2,NULL,(void*)(&print_msg),(void* )msg2);
    // 线程传参
    sleep(2);
    return 0;

}

运行结果:

Let's go    
Thread_id is 7fb19a42f700______WORLD 
Thread_id is 7fb19ac30700______Hello 

——————————2个新线程的执行顺序是反的,什么鬼!!
demo3.cpp 线程如何调用类中函数——static

#include <iostream>
#include <pthread.h>

using namespace std;

class hello
{
    public:
    static void* sayhello(void* args) //static 
        {
        cout << "hello class..."<< endl;
        }
};
int main()
{
    pthread_t pid[5];
    for(int i =0; i < 5; i++)
    {
    int ret = pthread_create(&pid[i],NULL,hello::sayhello,NULL);
    if(ret != 0)
        cout << "Pthread_create failed .."<< endl;
    }
    pthread_exit(NULL);////等各个线程退出后,进程才结束,否则进程强制结束了,线程可能还没反应过
来;
    return 0;
}

demo3.cpp 线程退出状态和线程属性

#include <iostream>
#include <pthread.h>

using namespace std;
#define NUM_THREADS 5

void* say_hello(void* args)
{
    cout << "___HELLO___ "<< *((int*)args) << endl;
    int status = 10 + *((int*)args); // 将参数+10
    pthread_exit((void*)status);//由于线程创建时提供了Jointable参数,这里可以在退出时添加退出信息;
    //status提供给主程序提取该线程退出线程的结束信息
}

int main()
{
    pthread_t tids[NUM_THREADS];
    int indexs[NUM_THREADS];
    pthread_attr_t attr;//第一步声明:线程属性,用于pthread_create创建时加入参数
    pthread_attr_init(&attr);//第二部:线程属性初始化
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
    //第三步:设置你要执行线程属性参数,该参数表明该线程是可以Join连接的,
    //join 表示主程序可以等线程结束后再执行,实现了**主程序和线程同步功能**
    for(int i = 0; i < NUM_THREADS; i++)
    {
    indexs[i]= i;   
    int ret = pthread_create(&tids[i],NULL,say_hello,(void *)&(indexs[i]));//4 arguments
    if(ret != 0)
        {
        cout << "Pthread create error !!!!"<< i <<"____"<< ret << endl;
        }

    else
        {
        cout << "main___"<< endl;
        }
    }
    pthread_attr_destroy(&attr); //创建线程后,该参数已经结束使命,必须销毁,防止内存泄漏。
    void* status;
    for(int i =0;i< NUM_THREADS;i++)
    {
        int ret = pthread_join(tids[i],&status);//前面创建了线程,这里主程序想要join 每个线程,然后取得每个线程的退出信息status.
        if(ret !=0)
            cout << "pthread_join_error: error code : "<< ret << endl;
        else
            cout << "pthread_join get status: " << (long )status << endl;
    }

    pthread_exit(NULL);
}

运行结果

main___
main___
main___
main___
main___
___HELLO___ 4
___HELLO___ 3
___HELLO___ 2
___HELLO___ 1
___HELLO___ 0
pthread_join get status: 10
pthread_join get status: 11
pthread_join get status: 12
pthread_join get status: 13
pthread_join get status: 14

——————————线程执行顺序依然是反的!
——————————主程序第一,然后是线程回调,最后是join 部分代码(主程序)(这一部分顺序确是对的,首先创建的线程遍历。)。
- joinable 和 detached 可结合 和 分离的
任何一个时间点,线程是可结合的joinable 或者分离的 detached. 线程的默认状态是非分离状态(即Joinable,需要回收)
Joinable:
能够被其他线程收回资源和杀死
在被其他线程回收前,它的存储器资源(如栈)是不释放的。
detached:
不能被其他线程回收或者杀死
它的存储器资源在它终止时由系统自动释放

可结合线程(Joinable):
    线程的**分离状态**决定一个线程以什么样的方式来终止自己。
    默认线程我们采用了线程非分离状态(即可结合的,joinable,需要回收)
    这种情况下,原有的线程等待创建的线程结束;**只有当pthread_join()函数返回时,创建的线程才算终止**,**才能释放自己占用的系统资源**。
    主线程需要**明确执行等待**操作,在子线程结束后,主线程的等待操作执行完毕,子线程和主线程会合,这时主线程继续执行等待操作之后的下一步操作。
分离线程(detached):
    分离线程不是这样子的,它没有被其他的线程所等待。
    自己运行结束了,线程也就终止了,马上释放系统资源。

线程的分离状态设置
    函数 pthread_attr_setdetachstate(pthread_attr_t* attr, int detachstate)
    第二个参数值选项为宏PTHREAD_CREATE_DETACHED(分离线程)和 PTHREAD _CREATE_JOINABLE(非分离线程)

注意点:
    如果设置一个线程为分离线程,而这个线程运行又非常快,它很可能在 pthread_create函数返回之前就终止了,它终止以后就可能将线程号和系统资源移交给其他的线程使用,这样调用pthread_create的线程就得到了错误的线程号。要避免这种情况可以采取一定的同步措施,最简单的方法之一是可以在被创建的线程里调用 pthread_cond_timewait函数,让这个线程等待一会儿,留出足够的时间让函数pthread_create返回。设置一段等待时间,是在多线程编程里常用的方法。
    如果创建Joinable 线程,那就在主程序中必须pthread_join() 进行资源回收。
#include <pthread.h>
void pthread_exit(void *retval);
void pthread_join(pthread_t th,void **thread_return);//主线程挂起等待th结束
//*thread_return=retval; 新线程结束返回状态,传给*thread_return
int pthread_detach(pthread_t th);

这里写图片描述
join()挂起

#include <pthread.h>
#include <stdio.h>

void print_msg(char *ptr){
    int i;
    for( i = 0; i < 10; i++)
        printf("_%s_",ptr);

}

int main()
{
    pthread_t thread1,thread2;
    int i ,j;
    void* retval;
    char* msg1= " Hello ";
    char* msg2 = " WORLD ";
    printf("****Let's go*** \n");
    pthread_create(&thread1,NULL,(void*)(&print_msg),(void *)msg1);
    pthread_create(&thread2,NULL,(void*)(&print_msg),(void* )msg2);

    pthread_join(thread1,&retval);
    printf("#####################################\n");
    printf("*************************************\n");
    pthread_join(thread2,&retval);
    printf("+++++++++++++++++++++++++++++++++++++\n");

    printf("ALL DONE !! MAIN");
    return 0;

}

运行结果:

robot@ubuntu:~/Documents/posix/1$ ./demo1join 
****Let's go*** 
_ WORLD __ WORLD __ WORLD __ WORLD __ WORLD __ WORLD __ WORLD __ WORLD __ WORLD __ WORLD __ Hello __ Hello __ Hello __ Hello __ Hello __ Hello __ Hello __ Hello __ Hello __ Hello _#####################################
*************************************
+++++++++++++++++++++++++++++++++++++
  1. 优先级使用数据结构

//参考自a_ran的csdn

struct sched_param
{
    int __sched_priority; //所要设定的线程优先级  1 -99 , 数字越大,优先级越高。
}
Linux内核的三种调度策略:

  1,SCHED_OTHER 分时调度策略,(不支持优先级)
  2,SCHED_FIFO实时调度策略,先到先服务。一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃
  3,SCHED_RR实时调度策略,时间片轮转。当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平
  设置和获取优先级的函数
  

    int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
   int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);
     param.sched_priority = 51; //设置优先级

系统默认创建线程使用的是SCHED_OTHER。 没有优先级。若要更改线程的调度策略,通过如下函数。

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

测试程序:

 #include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>

static int get_thread_policy(pthread_attr_t *attr)
{
  int policy;
  int rs = pthread_attr_getschedpolicy(attr,&policy);
  assert(rs==0);
  switch(policy)
  {
  case SCHED_FIFO:
    printf("policy= SCHED_FIFO\n");
    break;
  case SCHED_RR:
    printf("policy= SCHED_RR");
    break;
  case SCHED_OTHER:
    printf("policy=SCHED_OTHER\n");
    break;
  default:
    printf("policy=UNKNOWN\n");
    break;
  }
  return policy;
}

static void show_thread_priority(pthread_attr_t *attr,int policy)
{
  int priority = sched_get_priority_max(policy);
  assert(priority!=-1);
  printf("max_priority=%d\n",priority);
  priority= sched_get_priority_min(policy);
  assert(priority!=-1);
  printf("min_priority=%d\n",priority);
}

static int get_thread_priority(pthread_attr_t *attr)
{
  struct sched_param param;
  int rs = pthread_attr_getschedparam(attr,&param);
  assert(rs==0);
  printf("priority=%d",param.__sched_priority);
  return param.__sched_priority;
}

static void set_thread_policy(pthread_attr_t *attr,int policy)
{
  int rs = pthread_attr_setschedpolicy(attr,policy);
  assert(rs==0);
  get_thread_policy(attr);
}

int main(void)
{
  pthread_attr_t attr;
  struct sched_param sched;
  int rs;
  rs = pthread_attr_init(&attr);
  assert(rs==0);

  int policy = get_thread_policy(&attr);
  printf("Show current configuration of priority\n");
    show_thread_priority(&attr,policy);
  printf("show SCHED_FIFO of priority\n");
 show_thread_priority(&attr,SCHED_FIFO);
  printf("show SCHED_RR of priority\n");
  show_thread_priority(&attr,SCHED_RR);
  printf("show priority of current thread\n");
  int priority = get_thread_priority(&attr);

  printf("Set thread policy\n");
  printf("set SCHED_FIFO policy\n");
  set_thread_policy(&attr,SCHED_FIFO);
  printf("set SCHED_RR policy\n");
  set_thread_policy(&attr,SCHED_RR);
  printf("Restore current policy\n");
  set_thread_policy(&attr,policy);

  rs = pthread_attr_destroy(&attr);
  assert(rs==0);
  return 0;
}

运行结果:

policy=SCHED_OTHER
Show current configuration of priority
max_priority=0
min_priority=0
show SCHED_FIFO of priority
max_priority=99
min_priority=1
show SCHED_RR of priority
max_priority=99
min_priority=1
show priority of current thread
priority=0Set thread policy
set SCHED_FIFO policy
policy= SCHED_FIFO
set SCHED_RR policy
policy= SCHED_RRRestore current policy
policy=SCHED_OTHER

不同线程调度方案和优先级。
测试程序:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>

void Thread1()
{
  sleep(1);
  int i,j;
  int policy;
  struct sched_param param;
  pthread_getschedparam(pthread_self(),&policy,&param);
  if(policy == SCHED_OTHER)
    printf("SCHED_OTHER\n");
  if(policy == SCHED_RR);
  printf("SCHED_RR 1 \n");
  if(policy==SCHED_FIFO)
    printf("SCHED_FIFO\n");

  for(i=1;i<10;i++)
  {
    for(j=1;j<5000000;j++)
    {
    }
    printf("thread 1\n");
  }
  printf("Pthread 1 exit\n");
}

void Thread2()
{
  sleep(1);
  int i,j,m;
  int policy;
  struct sched_param param;
pthread_getschedparam(pthread_self(),&policy,&param);
 if(policy == SCHED_OTHER)
    printf("SCHED_OTHER\n");
  if(policy == SCHED_RR);
  printf("SCHED_RR\n");
  if(policy==SCHED_FIFO)
    printf("SCHED_FIFO\n");

  for(i=1;i<10;i++)
  {
    for(j=1;j<5000000;j++)
    {

    }
    printf("thread 2\n");
  }
  printf("Pthread 2 exit\n");
}

void Thread3()
{
  sleep(1);
  int i,j;
  int policy;
  struct sched_param param;
pthread_getschedparam(pthread_self(),&policy,&param);
 if(policy == SCHED_OTHER)
    printf("SCHED_OTHER\n");
  if(policy == SCHED_RR)
    printf("SCHED_RR \n");
  if(policy==SCHED_FIFO)
    printf("SCHED_FIFO\n");

  for(i=1;i<10;i++)
  {
    for(j=1;j<5000000;j++)
    {
    }
    printf("thread 3\n");
  }
  printf("Pthread 3 exit\n");
}

int main()
{
  int i;
  i = getuid();
  if(i==0)
    printf("The current user is root\n");
  else
    printf("The current user is not root\n");

  pthread_t ppid1,ppid2,ppid3;
  struct sched_param param;

  pthread_attr_t attr,attr1,attr2;

  pthread_attr_init(&attr1);
pthread_attr_init(&attr);
pthread_attr_init(&attr2);
  param.sched_priority = 51;
 pthread_attr_setschedpolicy(&attr2,SCHED_RR);
 pthread_attr_setschedparam(&attr2,&param);
 pthread_attr_setinheritsched(&attr2,PTHREAD_EXPLICIT_SCHED);//要使优先级其作用必须要有这句话

 param.sched_priority = 21;
 pthread_attr_setschedpolicy(&attr1,SCHED_RR);
 pthread_attr_setschedparam(&attr1,&param);
 pthread_attr_setinheritsched(&attr1,PTHREAD_EXPLICIT_SCHED);

 pthread_create(&ppid3,&attr,(void *)Thread3,NULL);
 pthread_create(&ppid2,&attr1,(void *)Thread2,NULL);
 pthread_create(&ppid1,&attr2,(void *)Thread1,NULL);

 pthread_join(ppid3,NULL);
 pthread_join(ppid2,NULL);
 pthread_join(ppid1,NULL);
 pthread_attr_destroy(&attr2);
 pthread_attr_destroy(&attr1);
 return 0;
}

运行结果:

robot@ubuntu:~/Documents/posix/2$ ./thread2 
The current user is not root
SCHED_OTHER
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
Pthread 3 exit
robot@ubuntu:~/Documents/posix/2$ sudo ./thread2 
[sudo] password for robot: 
The current user is root
SCHED_RR 1 
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
Pthread 1 exit
SCHED_RR
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
Pthread 2 exit
SCHED_OTHER
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
Pthread 3 exit
robot@ubuntu:~/Documents/posix/2$
  1. 互斥锁和条件变量
    mutual exclusion 互相排斥,互斥锁锁的是线程,而保护公共区域数据,是因为多个线程均使用了互斥锁。
#include <stdio.h>
#include <pthread.h>

#define FALSE 0
#define TRUE 1

void readfun();
void writefun();

char buffer[256]; // 公共数据区
int buf_has_item = 0;//设置数据区的标志位
int retFLAG = FALSE ;//
pthread_mutex_t mutex;//互斥锁全局变量

int main()
{
    pthread_t reader;
    pthread_mutex_init(&mutex,NULL);
    pthread_create(&reader,NULL,(void *)(&readfun),NULL);
    writefun();// 先写再读,该处write 速度比新线程要快,所以先看writefun()
    return 0;

}


void readfun()
{
    while(TRUE)
    {
        if(retFLAG)
            return;
        pthread_mutex_lock(&mutex);
        if(buf_has_item== 1)
        {
            printf("%s",buffer);
            buf_has_item = 0;
        }
        pthread_mutex_unlock(&mutex);

    }
}

void writefun()
{
    int i = 0;//这个i 是和while 要进行遍历,但是下面的if--return ,限制了循环次数。while(1)---return;
    //return 的作用是退出循环体所在的函数,相当于结束该方法。
    while(TRUE)
    {
        if(i == 10)
        {
            retFLAG = TRUE;
            return;//return 和循环没关系,就是跳出该函数

        }
        pthread_mutex_lock(&mutex); //先上锁,新线程阻塞!
        if(buf_has_item == 0)//判断状态位置
        {
            sprintf(buffer,"This is %d\n",i++);
            buf_has_item = 1;  //该状态位为 readfun()判断使用。
        }
    pthread_mutex_unlock(&mutex);
    }

}

结果为:

robot@ubuntu:~/Documents/posix/3$ ./mutex 
This is 0
This is 1
This is 2
This is 3
This is 4
This is 5
This is 6
This is 7
This is 8   //共循环9次。i++ 0-8;如果writefun()中sprintf改成(++i)就会是循环1-9次
  1. 条件变量
    互斥锁只有两个状态,不能满足常用的使用方式,所以条件变量和互斥锁常常搭配使用,控制线程间的工作方式
//初始化条件变量
pthread_cond_t cond;
int pthread_cond_init(pthread_cond_t *cond,const pthread_cond_attr *attr);
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_wait(pthread_cond_t *cond,pthread_murex_t *mutex);
//函数将阻塞,直到条件变量获得信号或者经过abstime指定的时间。
int pthread_cond_timewait(pthread_cond_t *cond,pthread_murex_t *mutex,const struct timespec* abstime);
//发送信号
int pthread_cond_signal(pthread_cond_t *cond)
//使得所有关于由参数cond 指向的条件变量阻塞的线程退出阻塞状态。参数没有mutex,并不指向使用锁的且阻塞的线程。
int pthread_cond_broadcast(pthread_cond_t *cond)

条件变量demo

#include <pthread.h>
#include <iostream>

using namespace std;

#define BOUNDARY 5 //全局变量
int task = 10;

pthread_mutex_t task_mutex;//锁
pthread_cond_t task_cond;//条件变量,设为全局

void* say_hello2(void* args)
{
    pthread_t pid = pthread_self();//获得线程资源编号
    cout<< "["<< pid << "] hello in thread" << *((int*)args)<< endl;

    bool is_signaled = false ; //随便设置的标志位,用于条件切换,发送信号

    while(1)
    {
        pthread_mutex_lock(&task_mutex);//先锁,再判断。
        if(task > BOUNDARY)
        {
            cout << "["<<pid <<"] take task :"<< task << "in thread"<<*((int*)args) << endl;
            --task;
        }
        else if (!is_signaled)
        {
            cout << "["<<"] pthread_cond_signal in thread " << *((int *)args)<< endl;
            pthread_cond_signal(&task_cond);//重点发送信号
            is_signaled = true ;
        }
        pthread_mutex_unlock(&task_mutex);
        if(task == 0)// 用于跳出while
            break;
    }
}

void* say_hello1(void* args)
{
    pthread_t pid = pthread_self();
    cout << "["<<pid <<"] hello in thread "<< *((int*)args)  << endl;
    while(1)
    {
        pthread_mutex_lock(&task_mutex);
        if(task > BOUNDARY)
        {
            cout <<"["<< pid <<"] pthread_cond_wait in thread" << *((int*) args) << endl;
            pthread_cond_wait(&task_cond,&task_mutex);//重点,收到信号前阻塞
        }
        else
        {
            cout << "["<< pid << "] take task:"<< task << "in thread "<< *((int* )args) << endl;
            --task;
        }
        pthread_mutex_unlock(&task_mutex);
        if(task ==0)//小于5时,会空循环5次,直到==0,break
            break;
    }
}

int main()
{
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);//为下面Join

    pthread_mutex_init(&task_mutex,NULL);

    pthread_cond_init(&task_cond,NULL);

    pthread_t tid1,tid2;
    int index1 =1, index2 =2 ;
    int ret1 = pthread_create(&tid1,&attr,say_hello1,(void*)&index1);
    if(ret1 != 0)
        cout << "pthread 1 create failed ! error code is "<< ret1 << endl;
    int ret2 = pthread_create(&tid2,&attr,say_hello2,(void*)&index2);
    if(ret2 !=0)
        cout << "pthread 2 create failed ! error code is "<< ret2 << endl;
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);

    pthread_attr_destroy(&attr);
    pthread_mutex_destroy(&task_mutex);
    pthread_cond_destroy(&task_cond);

    return 0;
}

运行结果:

robot@ubuntu:~/Documents/posix/3$ ./cond1 
[140355188872960] hello in thread2
[140355188872960] take task :10in thread2
[140355188872960] take task :9in thread2
[140355188872960] take task :8in thread2
[140355188872960] take task :7in thread2
[140355188872960] take task :6in thread2
[] pthread_cond_signal in thread 2
[140355197265664] hello in thread 15
[140355197265664] take task:5in thread 1
[140355197265664] take task:4in thread 1
[140355197265664] take task:3in thread 1
[140355197265664] take task:2in thread 1
[140355197265664] take task:1in thread 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值