线程函数和类型介绍

1. pthread_t

表示线程 ID

typedef unsigned long int pthread_t


 

2. pthread_attr_t

线程属性结构信息

 

typedef struct

{

       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;


用 pthread_attr_init 函数初始化这个结构

用 pthread_attr_destory 给这个结构去除初始化

用 pthread_set_detachstate 对这个属性设置线程分离状态

下面是这三个函数的声明和注释:

/* Thread attribute handling.  */

/* Initialize thread attribute *ATTR with default attributes
   (detachstate is PTHREAD_JOINABLE, scheduling policy is SCHED_OTHER,
    no user-provided stack).  */
extern int pthread_attr_init (pthread_attr_t *__attr) __THROW __nonnull ((1));

/* Destroy thread attribute *ATTR.  */
extern int pthread_attr_destroy (pthread_attr_t *__attr)
     __THROW __nonnull ((1));

/* Get detach state attribute.  */
extern int pthread_attr_getdetachstate (__const pthread_attr_t *__attr,
                                        int *__detachstate)
     __THROW __nonnull ((1, 2));

/* Set detach state attribute.  */
extern int pthread_attr_setdetachstate (pthread_attr_t *__attr,
                                        int __detachstate)
     __THROW __nonnull ((1));

 

links: http://blog.chinaunix.net/space.php?uid=9532036&do=blog&cuid=341886

 

3. pthread_mutex_t

线程互斥锁

pthread_mutex_lock 加锁

pthread_mutex_unlock 解锁


4.  pthread_create

创建一个线程

#include <pthread.h> 

/* Create a new thread, starting with execution of START-ROUTINE
   getting passed ARG.  Creation attributed come from ATTR.  The new
   handle is stored in *NEWTHREAD.  */
extern int pthread_create (pthread_t *__restrict __newthread,
                           __const pthread_attr_t *__restrict __attr,
                           void *(*__start_routine) (void *),
                           void *__restrict __arg) __THROW __nonnull ((1, 3));


Returns: 0 if OK, error number on failure

4. 编译链接:

程序需要链接线程库

gcc -o target -lpthread xxx.c

 

<think>好的,用户问为什么线程函数类型是void *。首先,我需要回顾之前讨论的内容。用户之前询问了关于不使用Windows API的跨平台实现,我介绍了POSIX线程信号量的用法,并给出了代码示例。现在用户关注的是线程函数返回类型为什么是void *。 这可能是因为用户在阅读示例代码时,注意到线程函数threadFunction的返回类型是void*,而对此感到疑惑。用户可能不太明白为什么线程函数需要返回指针类型,而不是更常见的基本类型,比如int或者void。 接下来,我需要从C语言POSIX线程的标准来解释这个问题。首先,POSIX线程(pthread)库规定线程函数的签名必须返回void*,并接受一个void*参数。这是为了提供最大的灵活性,允许线程函数传递任意类型的数据。如果返回类型不是指针,那么可能无法传递复杂的数据结构,而只能返回简单的整数值,这会限制线程的用途。 然后,我需要解释void*的作用。void*在C语言中是通用指针类型,可以指向任何数据类型。使用void*作为返回类型参数类型,使得线程函数可以接收返回任意类型的指针,用户在使用时需要进行类型转换。例如,线程可能需要返回一个结构体指针,或者一个整数的指针,这样可以传递更多的信息。 另外,需要提到线程创建函数pthread_create的参数。pthread_create的第三个参数是线程函数的指针,而第四个参数是传递给线程函数的参数,类型是void*。同样,线程函数返回的void*可以通过pthread_join获取,这样主线程可以获取子线程的返回结果。 可能用户还会疑惑,如果线程不需要返回值怎么办。这时候可以说明,即使不需要返回值,线程函数仍然需要返回void*,可以简单地返回NULL。同时,如果不需要参数,可以在创建线程时传递NULL,或者忽略参数。 另外,可能需要比较其他语言或框架中的线程函数设计,例如C++的std::thread接受任意可调用对象,但C语言由于缺乏模板重载,需要通过void*来实现通用性。 还要考虑用户可能的误解,比如是否必须返回有效的指针,或者是否可以返回其他类型。需要澄清,返回类型必须是指针,但可以返回NULL,或者通过类型转换将整数转换为指针传递,但需要注意平台兼容性安全性问题。 最后,总结这种设计的原因:标准化接口、灵活性、跨平台兼容性,以及如何在实际使用中正确处理类型转换资源管理。可能还需要提醒用户在使用时要注意内存管理,避免悬垂指针等问题。</think>### **线程函数返回`void*`类型的设计解析** 在C语言的POSIX线程(pthread)库中,线程函数的返回类型参数类型均为`void*`,这种设计主要基于以下原因: --- #### **1. 标准化接口需求** POSIX线程库需要提供一个**统一的函数签名**,以适配所有可能的线程使用场景。通过`void*`类型(通用指针),线程函数可以: - **接收任意类型的参数**(通过指针传递) - **返回任意类型的结果**(通过指针返回) 例如: ```c void* threadFunction(void* arg) { // 将参数转换为实际类型(如int*、结构体指针等) int* input = (int*)arg; // 处理逻辑... int* result = malloc(sizeof(int)); *result = (*input) * 2; return (void*)result; // 返回结果指针 } ``` --- #### **2. 灵活性与数据封装** - **参数传递**: 调用`pthread_create`时,第四个参数为`void*`,允许传递任意数据的地址: ```c int value = 42; pthread_create(&thread, NULL, threadFunction, &value); // 传递int的地址 ``` - **返回值获取**: 通过`pthread_join`可以接收线程的返回结果(`void*`类型): ```c void* retVal; pthread_join(thread, &retVal); int* result = (int*)retVal; // 转换为实际类型 ``` --- #### **3. 兼容性与资源管理** - **无返回值场景**: 若线程无需返回值,可直接返回`NULL`: ```c void* threadFunction(void* arg) { // 无需返回数据 return NULL; } ``` - **动态内存管理**: 若返回堆内存指针,需由调用者负责释放: ```c int* result = malloc(sizeof(int)); *result = 100; return result; // 主线程中需手动free(retVal) ``` --- #### **4. 对比其他语言的实现** - **C++的`std::thread`**: 通过模板函数重载支持任意函数签名,但C语言缺乏此特性,因此需依赖`void*`的通用性。 - **Java的`Runnable`接口**: 类似地,Java线程通过`run()`方法返回`void`,但使用对象封装参数结果,而C语言需手动管理指针。 --- ### **关键代码示例** ```c #include <pthread.h> #include <stdio.h> #include <stdlib.h> // 线程函数:计算平方值 void* square(void* arg) { int* num = (int*)arg; int* result = malloc(sizeof(int)); *result = (*num) * (*num); return (void*)result; } int main() { pthread_t thread; int input = 5; // 创建线程并传递参数 pthread_create(&thread, NULL, square, &input); // 等待线程完成并获取结果 void* retVal; pthread_join(thread, &retVal); // 转换结果类型并输出 int* result = (int*)retVal; printf("平方值: %d\n", *result); // 输出25 free(result); // 释放堆内存 return 0; } ``` --- ### **常见问题解答** #### **Q1: 如果不需要参数或返回值,如何处理?** - **无参数**:传递`NULL`给`pthread_create`: ```c pthread_create(&thread, NULL, threadFunction, NULL); ``` - **无返回值**:直接返回`NULL`: ```c void* threadFunction(void* arg) { // 无返回操作 return NULL; } ``` #### **Q2: 为什么不用`int`或`void`作为返回类型?** - **`int`的限制**:无法返回复杂数据(如结构体、字符串等)。 - **`void`的限制**:无法返回任何数据,失去线程间通信能力。 #### **Q3: 如何避免类型转换的错误?** - **显式类型检查**:确保转换前后类型匹配。 - **使用联合体(Union)**:封装多种数据类型(需配合标识字段)。 --- ### **总结** | 设计选择 | 原因与优势 | |-------------------|--------------------------------------------------------------------------| | **`void*`参数类型** | 支持传递任意数据指针,灵活性高 | | **`void*`返回类型** | 允许线程返回复杂结果,统一接口适配多场景 | | **类型转换机制** | 通过强制转换实现类型适配,需开发者保证安全性 | 通过`void*`的设计,C语言线程模型在有限的语法特性下,实现了最大程度的**灵活性扩展性**,但也要求开发者对内存管理类型安全保持高度警惕。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值