高级编程之线程(二)

来源:互联网 发布:成都理工大学网络登录 编辑:程序博客网 时间:2024/05/29 15:44

线 程 的 传 参


 

1、pthread_create(tid,NULL,fun,arg);  ===>arg 回调函数参数


1.1  向子线程中传入数字
 

1.2  向子线程中传入字符串


1.3  向子线程中传入结构体


练习:设计一个多线程函数,并向其中送入一个结构体变量
   在线程中打印输出结构体变量的所有成员变量值。


2 、多线程的互斥 ===》互斥锁 ====》pthread_mutex_t 类型的锁
  
    目的:保护临界资源的排他性访问。

操作流程:

 0:定义一个全局的互斥锁变量:
   静态变量: pthread_mutex_t  mutex;
   动态变量: pthread_mutex_t mutex = malloc();
      free();

 1、初始化互斥锁  pthread_mutex_init()
    原型:int pthread_mutex_init(pthread_mutex_t * mutex const pthread_mutexattr_t * attr);

    功能:该函数用于线程中初始化设置一个已经定义的互斥锁。
       一般用于线程的创建者执行。

    参数: mutex  已经定义的互斥锁
        attr   互斥锁的属性,默认属性是NULL;
    返回值:成功 0
         失败  -1;

 

 2、加锁  pthread_mutex_lock()
  原型:int pthread_mutex_lock(pthread_mutex_t *mutex);
  功能:用来控制临界资源的访问,如果该代码执行
   则在解锁之前,该代码之后的所有语句都执行原子操作。

     参数: mutex 执行过程中的互斥锁
  返回值:成功  0
    失败   -1


 3、解锁  pthread_mutex_unlock();
  原型:int pthread_mutex_unlock(pthread_mutex_t *mutex);
  功能:该函数用于之前加锁的进程执行解锁动作。
  参数: mutex 要执行解锁任务的互斥锁。
  返回值:成功  0
    失败  -1;


 4、销毁锁   pthread_mutex_destroy();
  原型 :int pthread_mutex_destroy(pthread_mutex_t *mutex);
  功能:用来销毁不再使用的互斥锁,如果其他进程要用就必须重新
     初始化并加解锁。
  参数: mutex 要操作的互斥锁
  返回值:成功  0
    失败  -1;

问题:
1、该部分代码要验证什么问题?
2、代码中的 _LOCK_ 是什么含义,有什么作用。
3、该部分代码执行过程中有几个线程
4、代码执行的结果是什么? 能否改进。


练习:
 设计一个多线程任务,尝试不同的线程同时进行文件写操作。
 要求每个线程写入的信息不能交叉不能覆盖。
 建议:使用互斥锁实现。


3、多线程的同步操作:===》信号量  ===>二值信号量

   头文件: semaphore.h

  操作流程: 信号量的定义  ===》定义变量
      信号量的初始化  ===》sem_init
    信号量的PV操作  ===》sem_wait ==>p  sem_post ==>v
         p操作: 申请信号量资源
        v操作: 释放信号量资源
    信号量的销毁  ===》sem_destroy

 

   定义变量: sem_t sem   ==>用sem_t 类型来定义一个信号量
          可以是全局变量也可以是堆区变量

   信号量的初始化: sem_init()
   原型:int sem_init(sem_t *sem, int pshared, unsigned int value);
   功能:将已经申请的信号量做初始化赋值
   参数:sem 信号量
      pshared  使用范围: 0 线程间使用 非0 进程间使用
   value  信号量的初始值。如果是0 则进程在申请资源时候阻塞
            1 则进程可以申请资源。
   返回值:成功 0
        失败  -1;


 信号量的PV操作
 1、p操作:int sem_wait(sem_t *sem);
  功能:该函数用于线程间测试信号量资源是否可以使用。
    如果sem是0 ,则该线程阻塞等待。
    如果sem是1,则线程继续运行,
        同时sem值减1==》sem = sem-1;
  参数:sem 要检测的信号量
  返回值:成功 0
    失败  -1;
 2、v操作:int sem_post(sem_t *sem);
  功能:该函数用于线程使用完毕信号量并释放资源。
    该函数不会阻塞线程,默认会进行sem= sem+1;
  参数:sem 要操作的信号量
  返回值:成功 0
    失败  -1;

 
 信号量的销毁:int sem_destroy(sem_t *sem);
 功能:在信号量使用完毕后,对该资源回收。
 参数:sem 要回收的信号量
 返回值:成功 0
   失败 -1;


信号量的当前值查询: int sem_getvalue(sem_t *sem, int *sval);
      功能:获取当前信号量的值
   参数:sem要获取当前值的信号量
       sval 要获取的值的内存空间,需要实现定义变量。
   返回值:成功  0
      失败  -1;

练习:
 使用以上信号量的知识,设计一个多线程程序,完成如下功能:
 1、尽可能少的申请线程
 2、一个线程动态获取用户输入
 3、另一个线程将用户输入的字符,统计并将个数打印输出。


作业:
 用多线程实现火车票售票系统,要求至少有两个售票窗口。
 从以上窗口中均匀的卖出100张火车票,每个窗口不能重复卖票。
 ./a.out


 window 1 sale 1
 window 2 sale 2
 ......

0 0
原创粉丝点击