`
mylxiaoyi
  • 浏览: 328447 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

POSIX线程-(五)

阅读更多


线程属性

当我们第一次了解线程时,我们并没有讨论线程属性的问题。我们现在会进行讨论。线程有许多我们可以控制的属性。然而,在这里我们只讨论那些我们最需要的线程属性。其他属性的详细信息可以在手册中了解到。

在所有我们前面的例子中,我们不得不在允许程序退出之前使用pthread_join来重新同步我们的线程。如里我们希望允许一个线程向创建他的线程返回数据时我们需要这样做。有时我们并不需要第二个线程向主线程返回信息,也不希望主线程等待第二个线程。

假设我们创建了第二个线程来备份正在编辑的数据文件的一份拷贝,而主线程继续向用户服务。当备份完成时,第二个线程只是简单的退出,并没有需要与主线程聚合。

我们可以创建类似这样行为的线程。他们被称之为分离线程,而我们可以通过修改线程属性或是通守调用pthread_detach来创建这样的线程。因为在这里我们希望演示线程属性,我们将会使用前一种方法。

我们所需要的最重要的函数就是pthread_attr_init,这个函数可以初始化一个线程属性对象。

#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);

再一次说时,如果成功则返回0,如果失败则会返回一个错误代码。

同时存在一个销毁函数:pthread_attr_destroy。这个函数的目的就是允许清除属性对象。一旦对象已经被销毁,这个属性对象就不可以被再次使用,直到他被初始化。

当我们有一个已经初始化的线程属性时,有许多我们可以调用的额外函数来设置不同的属性行为。我们在这里列出一些主要的函数,但是我们只会了解其中的两个:

int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
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);
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit);
int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit);
int pthread_attr_setscope(pthread_attr_t *attr, int scope);
int pthread_attr_getscope(const pthread_attr_t *attr, int *scope);
int pthread_attr_setstacksize(pthread_attr_t *attr, int scope);
int pthread_attr_getstacksize(const pthread_attr_t *attr, int *scope);

正如我们所看到的,有许多我们可以使用的属性,但是幸运的是,我们通常并不会使用其中的大多数。

detachstate:这个属性允许我们避免线程重新聚合的需要。与大多数_set函数相似,他以一个指向属性的指针与一个决定所需状态的标记为参数。pthread_attr_setdetachstate函数的两个可能的标记值为PTHREAD_CREATE_JOINABLE与PTHREAD_CRATE_DETACHED。默认情况下,属性值为PTHREAD_CREATE_JOINABLE,从而我们可以允许两个线程重新聚合。如果状态设置为PTHREAD_CRATE_DETACHED,我们不能调用pthread_joi来恢复另一个线程的退出状态。

schedpolicy:这个属性控制线程是如何被调度的。其选项为SCHED_OTHER,SCHED_RR与SCHED_FIFO。默认情况下,属性值为SCHED_OTHER。另两个调度类型只在具有超级用户权限的情况下运行时才可用,因为他们都具有实时调度,但是却有略为不同的行为。SCHED_RR使用循环法调度,而SCHED_FIFO使用先进先出策略。这些属性的讨论超出本书的范围。

schedparam:这是schedpolicy的伙伴,而且允许我们控制使用策略SCHED_OTHER运行的线程的调度。我们会在本章的稍后部分看到使用这个参数的一个例子。

inheritsched:这个属性有两个可能的值:PTHREAD_EXPLICIT_SCHED与PTHREAD_INHERIT_SCHED。默认情况下,属性值为PTHREAD_EXPLICIT_SCHED,这就意味着调度是通过属性显示设置的。通过将其设置为PTHREAD_INHERIT_SCHED,新的线程就会使用其创建者线程所使用的参数。

scope:这个属性控制一个线程的调度是如何计算的。因为当前Linux只支持PTHREAD_SCOPE_SYSTEM,所以在这里我们并不会讨论这个特性。

stacksize:这个属性控制线程创建堆栈尺寸,以字节设置。这是规范中的"可选"部分,并且只在定义了_POSIX_THREAD_ATTR_STACKSIZE的实现上被支持。Linux默认情况下使用大堆栈来实现线程,所以这个特性在Linux上通常是丰富的。

试验--设置分离状态属性

作为我们分离线程的例子,thread5.c,我们创建了一个线程属性,将其设置为分离属性,然后使用这个属性来创建线程。现在当子线程完成时,他以正常的方式调用pthread_exit函数。然而,这次原始线程不再等待与他所创建的线程重新聚合。我们使用一个简单的thread_finished标记来允许主线程检测子线程是否已经结束,并且显示出线程仍共享变量。

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

void *thread_function(void *arg);

char message[] = "Hello World";
int thread_finished = 0;

int main()
{
int res;
pthread_t a_thread;

pthread_attr_t thread_attr;

res = pthread_attr_init(&thread_attr);
if(res != 0)
{
perror("Attribute creation failed");
exit(EXIT_FAILURE);
}
res = pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_DETACHED);
if(res != 0)
{
perror("Setting detached attribute failed");
exit(EXIT_FAILURE);
}
res = pthread_create(&a_thread,&thread_attr,thread_function,(void *)message);
if(res != 0)
{
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
(void)pthread_attr_destroy(&thread_attr);
while(!thread_finished)
{
printf("Waiting for thread to say it's finished...\n");
sleep(1);
}
printf("Othread thread finished,bye!\n");
exit(EXIT_SUCCESS);
}

void *thread_function(void *arg)
{
printf("thread_function is running. Argument was %s\n",(char *)arg);
sleep(4);
printf("Second thread setting finished flag, and exiting now\n");
thread_finished = 1;
pthread_exit(NULL);
}

正如我们所看到的,设置分离状态允许第二个线程独立完成,而不需要主线程来等待第二个线程。

工作原理

两个重要的代码段为:

pthread_attr_t thread_attr;
res = pthread_attr_init(&thread_attr);
if (res != 0) {
perror("Attribute creation failed");
exit(EXIT_FAILURE);
}

这声明了一个线程属性并且进行了初始化,另一段代码为:

res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
if (res != 0) {
perror("Setting detached attribute failed");
exit(EXIT_FAILURE);
}

这段代码设置属性值为分离状态。

另一个不同的地方就是创建线程,此时传递属性地址,

res = pthread_create(&a_thread, &thread_attr, thread_function, (void
*)message);

并且为了完整性,当我们使用完这个属性之后要销毁这个属性:

pthread_attr_destroy(&thread_attr);

分享到:
评论

相关推荐

    x86-64-12.2.0-release-posix-seh-msvcrt-rt-v10-rev2

    标题 "x86-64-12.2.0-release-posix-seh-msvcrt-rt-v10-rev2" 指的是一个针对x86_64架构的GCC编译器版本,该版本是12.2.0,定位为“release”发布版,具有POSIX线程(pthread)支持,使用SEH(结构化异常处理)机制...

    x86-64-posix-seh和MinGW-W64-install.exe

    SEH在处理异常时具有高效性和线程安全的特性,特别适合多线程环境。而在64位模式下,x86-64-posix-seh是对SEH的一种扩展,它遵循POSIX标准,使得在Windows系统上编译的程序可以更好地兼容Unix-like系统的行为。 ...

    i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z

    MinGW-W64的32位安装包:i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z ,支持GCC8.1.0,线程模型为posix,异常处理模型为dwarf, 解压后即可使用。 mingw-w64 版本选择方法: 32位系统选择i686, 64位系统选择x86_...

    mingw-x86-64-8.1.0-release-posix-seh-rt-v6-rev

    在某些情况下,如在多线程程序或者需要跨平台兼容性的项目中,开发者可能会选择SJLJ。 这个版本的MinGW-w64包含了GCC(GNU Compiler Collection),这是一个开源的编译器套件,支持多种编程语言,包括C、C++、...

    x86_64-8.1.0-release-posix-seh-rt_v6-rev0 (1).zip

    标题 "x86_64-8.1.0-release-posix-seh-rt_v6-rev0 (1).zip" 提供的信息表明,这是一个针对x86_64架构的软件包,版本号为8.1.0,类型是release(正式发布版),并且具有POSIX线程(posix-seh)支持,RT_v6指的是实时...

    i686-7.3.0-release-posix-dwarf-rt_v5-rev0.7z

    线程模型:win32 : 没有C ++ 11多线程特性, posix : 支持C ++ 11多线程特性; 异常处理模型:32位系统推荐dwarf,64位系统推荐seh。seh 是新发明的,而 sjlj 则是古老的。seh 性能比较好,但不支持 32位, sjlj 稳定...

    windows posix 线程库

    本文将详细讨论“Windows POSIX线程库”及其在Windows环境下实现POSIX线程(pthreads)的功能,以及如何利用该库实现Linux多线程代码在Windows上的运行。 POSIX线程库,通常称为pthreads,是UNIX系统中广泛使用的多...

    (中英文)-POSIX多线程程序设计-Programming with POSIX Threads

    本书深入浅出地介绍了POSIX线程(也称为pthreads)API,是理解并掌握多线程编程的重要参考资料。在本文中,我们将探讨POSIX线程的基本概念、API用法以及在实际开发中的应用。 1. **POSIX线程基础** - POSIX线程,...

    POSIX线程编程指南

    ### POSIX线程编程指南 #### 一、线程创建 ##### 1.1 线程与进程 在计算机科学领域,线程是程序执行的基本单位之一,它比进程更接近于执行体的概念。线程可以与其他同属于一个进程中的线程共享数据,但是每个线程...

    PosixThread - 20200228.rar

    利用Posix线程,开发者可以编写出高度可移植的多线程程序,使得代码可以在各种支持Posix的平台上运行,如Linux、macOS、FreeBSD等。 该线程池封装的主要特点是防止任务丢失。在高并发环境下,如果线程池的大小固定...

    posix线程详解.pdf(中文版)

    ### Posix线程详解 #### 1. 线程与进程的概念对比 在计算机科学领域,线程和进程都是实现程序并发执行的基本单位,但它们之间存在显著的区别。线程,尤其是POSIX线程(Portable Operating System Interface ...

    mingw-w64_x86_64-7.1.0-release-posix-seh-rt_v5-rev0

    7. **rt_v5**: 这可能指的是Runtime Library的版本,rt表示运行时库,用于提供基本的系统功能,如内存分配、线程管理和动态链接等。"v5"表示第五版,意味着这个版本可能包含了之前的版本改进和新增功能。 8. **rev0...

    Posix线程(经典)

    Posix线程(经典) Posix线程是指符合 POSIX 标准的多线程技术,可以将一个进程分解成多条执行线程,每条线程都可以独立运行,并共享所在进程的资源。Posix线程技术可以提高系统的并发性和响应速度,提高系统的性能和...

    x64-4.8.1-release-posix-seh-rev5

    这个版本是4.8.1,并且采用了“release”构建类型,POSIX线程模型("posix-seh")以及异常处理机制("seh")。"rev5"则表示这是一个修订版,可能是对先前版本的改进或修复。 描述中提到的"ming64"是MinGW-w64的一...

    POSIX多线程程序设计.pdf

    《POSIX多线程程序设计》深入描述了IEEE的开放系统接口标准——POSIX线程,通常称为Pthreads标准。本书首先解释了线程的基本概念,包括异步编程、线程的生命周期和同步机制;然后讨论了一些高级话题,包括属性对象、...

    POSIX多线程程序设计

    内容提要, 本书深入描述了IEEE的开放系统接口标准-POSIX线程,通常称为Pthreads标准。本, 书首先解释了线程的基本概念,包括异步编程、线程的生命周期和同步机制;然后讨论了, 一些高级话题,包括属性对象、线程私有...

    POSIX线程编程指南(合集)

    POSIX线程编程指南,通常被称为Pthreads,是操作系统接口的一部分,用于支持多线程编程。这个合集可能包含了深入的教程和实例,帮助开发者理解和掌握如何在遵循POSIX标准的系统上创建和管理线程。以下是关于POSIX...

    Posix线程编程指南.pdf

    ### Posix线程编程指南:线程创建与取消详解 #### 一、线程与进程的概念及区别 在深入探讨Posix线程编程之前,理解线程与进程的基本概念及其区别至关重要。线程,作为执行体的一个更轻量级单位,能够在同一进程中...

    Posix线程编程指南

    POSIX线程编程是指使用POSIX线程(通常称为pthread)库在类Unix操作系统上进行多线程编程的过程。POSIX线程库是一系列用于创建和管理线程的C语言接口,它被广泛应用于Linux和其他类Unix系统中。该指南将详细介绍...

Global site tag (gtag.js) - Google Analytics