AUPE学习第十二章------线程控制

本章讨论同一进程中的多个线程之间如何保持数据的私有性,最后讨论基于进程的系统调用如何与线程进行交互。

可以通过sysconfig函数来得到系统中的限制,包括线程限制。这些限制是为了增强应用程序在不同的操作系统实现之间的可移植性。

12.3线程属性

线程属性的数据类型是pthread_attr_t结构的指针。

可以用下面的方法初始化和去除线程的属性:

#include  <pthread.h>

int  pthread_attr_init(  pthread_attr_t  *attr)

int  pthread_attr_destroy( pthread_attr_t  *attr)

我们可以用专门的函数来得到和修改线程属性的各种值。

线程的属性主要有:线程的分离状态、线程栈末尾的警戒缓冲区大小、线程栈的最低地址、线程栈的大小。


可以用下面的函数得到线程的分离状态:

#include  <pthread.h>

int pthread_attr_getdetachstat( const  pthread_attr_t  *restrict  attr,  int  *detachstate);

int  pthread_attr_setdetachstate( pthread_attr_t  *attr,  int  detachstate)


分离状态创建线程:

[root@localhost apue]# cat page315.c 
#include "apue.h"
#include <pthread.h>

int makethread(void * (*fn)(void *), void *arg)
{
        int err;
        pthread_t tid;
        pthread_attr_t attr;
        err = pthread_attr_init(&attr);
        if(err != 0)
                return (err);
        err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
        if(err == 0)
                err = pthread_create(&tid, &attr, fn, arg);
        pthread_attr_destory(&attr);
        return(err);
}

通过_POSIX_THREAD_ATTR_STACKADDR和_POSIX_THREAD_ATTR_STACKSIZE这两个符号来检查系统是否支持线程栈属性。如果定义了,则支持。

注意区分线程属性和线程栈属性。可以通过下面两个函数来查询和修改线程栈属性:

int  pthread_attr_getstack(  const  pthread_attr_t  *restrict  attr,  void  **restrict  statckaddr,  size_t  *restrict  stacksize)

int  pthread_attr_setstack(  const  pthread_attr_t  *attr,  void  *stackaddr,  size_t  *stacksize)

这两个函数也可以用于确定栈的最高和最低地址。


可以用下面两个函数设置或者读取线程属性stacksize。

int  pthread_attr_getstacksize(cosnt  pthread_attr_t  *restrict  attr,  size_t   *restrict  stacksize)

int  pthread_attr_setstacksize(pthread_attr_t  *attr,  size_t  stacksize)


guardsize函数控制着线程栈末尾之后用以避免栈溢出的扩展内存的大小。下面函数用于操作:

int  pthread_attr_getguardsize(  const  pthread_attr_t  *restrict  attr,  size_t  *restrict  guardsize)

int  pthread_attr_setguardsize(  const  pthread_attr_t  *attr,  size_t  *guardsize)

线程还有一些没在pthread_attr_t结构中表达的属性:可取消状态、可取消类型、并发度。

并发度控制着用户级线程可以映射的内核线程或进程的数目。用下面函数得到和设置:

int   pthread_getconcurrency(void)

int   pthread_setconcurrency(int  level)


用户级线程和内核级线程的差别:

内核级线程操作系统内核实现、管理和调度的一种线程。由于有操作系统管理,所以操作系统是知道线程的存在,并为其安排时间片

,管理与其有关的内核对象。因为内核级线程是由内核来管理,所以每次线程创建、切换都要执行一个模式切换例程,所以内核级线程

效率比较低,而且内核级线程的调度是由操作系统的设计者来决定的,所以缺乏灵活性。但是内核级线程有一个有点就是当一个进程的

某个线程因为一个系统调用或者缺页中断而阻塞时,不会导致该进程的所有线程阻塞

内核级线程的优点:   较好的并行能力,一个进程内的线程阻塞不会影响该进程内的其他线程
内核级线程的缺点:  线程管理的开销过大,缺乏灵活性。

用户级线程是通过运行在用户态运行时库来管理的,其优点是,线程的一切(包括调度、创建)都可以完全由用户自己决定,

所以具有较高的灵活性。而且由于是在用户态上进行管理,所以就省去了内核管理的开销,所以具有高效率。 但是用户级线程

有一个致命的缺点:一个进程内的某一个线程阻塞将导致整个进程内的所有线程全部阻塞。而且由于用户级线程没有时间片

念,所以每个线程必须运行一段时间后将CPU让个其他的线程使用,否则,该线程将独占CPU。

用户级线程的优点: 有较高的灵活性和高效率
用户级线程的缺点: 较差并发能力

12.4同步属性

线程有属性,线程的同步对象也有属性。同步对象有互斥量、读写锁、条件变量。


可以用下面两个函数初始化和撤销互斥量的属性:

int   pthread_mutexattr_init( pthread_mutexattr_t  *attr)

int   pthread_mutexattr_destroy( pthread_mutexattr_t   *attr)  


互斥量同步对象的两个主要属性是:进程共享和类型。

在进程中,多个线程可以访问同一个同步对象。


多个进程也可以共享一个存储区域,称之为进程共享互斥量。可以用于进程的同步。下面的函数设置和修改进程共享互斥量的属性:

int   pthread_mutexattr_getpshared( const  pthread_mutexattr_t  *  restrict  attr,  int  *restrict  pshared)

int   pthread_mutexattr_setpshared( pthread_mutexattr_t   *attr,  int   pshared)


可以用下面函数得到和修改互斥量类型属性:

int   pthread_mutexattr_gettype( const  pthread_mutexattr_t  * restrict  attr,  int  *restrict  type)

int   pthread_mutexattr_settype(pthread_mutexattr_t   *attr,  int   type)



读写锁也有属性,读写锁属性用pthread_rwlockattr_t结构。可以用下面两个函数来初始化和回收读写锁属性。

int   pthread_rwlockattr_init(  pthread_rwlockattr_t   *attr)

int   pthread_rwlockattr_destroy( pthread_rwlockattr_t  *attr)

读写锁唯一支持的属性是进程共享属性。









  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你的问题我已经记下了,现在来回答你的问题。 为了方便您的阅读,我将第五章的补充案例和多线程部分分别介绍。 第五章补充案例: 在 PHP 中,我们可以通过 PHPMailer 库来实现邮件发送功能。PHPMailer 库是一个用于 PHP 的邮件发送类,它可以让我们方便地发送邮件并添加附件。下面是一个使用 PHPMailer 发送邮件的案例: ```php // 引入 PHPMailer 类文件 require_once('PHPMailer/PHPMailerAutoload.php'); // 实例化 PHPMailer 类 $mail = new PHPMailer(); // 设置邮件服务器的主机名、用户名和密码 $mail->isSMTP(); $mail->Host = 'smtp.gmail.com'; $mail->SMTPAuth = true; $mail->Username = '你的 Gmail 邮箱'; $mail->Password = '你的 Gmail 密码'; $mail->SMTPSecure = 'tls'; $mail->Port = 587; // 设置发件人信息 $mail->setFrom('发件人邮箱', '发件人名称'); // 设置收件人信息 $mail->addAddress('收件人邮箱', '收件人名称'); // 添加附件 $mail->addAttachment('附件文件路径', '附件文件名'); // 设置邮件主题和内容 $mail->Subject = '邮件主题'; $mail->Body = '邮件内容'; // 发送邮件 if ($mail->send()) { echo '邮件发送成功!'; } else { echo '邮件发送失败:' . $mail->ErrorInfo; } ``` 多线程部分: PHP 支持多线程编程,通过多线程可以提高程序的并发性和处理能力。在 PHP 中,我们可以使用 pthreads 扩展来实现多线程编程。pthreads 是一个开源的 PHP 扩展,它提供了多线程编程的基本功能,包括线程创建、同步、锁等。 下面是一个使用 pthreads 扩展创建线程的案例: ```php class MyThread extends Thread { public function __construct($name) { $this->name = $name; } public function run() { for ($i = 1; $i <= 10; $i++) { echo $this->name . ': ' . $i . "\n"; sleep(1); } } } $t1 = new MyThread('Thread 1'); $t2 = new MyThread('Thread 2'); $t1->start(); $t2->start(); ``` 在上面的案例中,我们定义了一个 MyThread 类,它继承自 Thread 类,并重写了 run() 方法。在 run() 方法中,我们输出线程的名称和计数器的值,并让线程休眠一秒钟。然后我们创建了两个 MyThread 对象,并分别启动了它们。最后,两个线程会同时执行,并输出各自的计数器值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值