关于封装fork/wait等操作, 编写函数 process_create(pid_t* pid, void* func, void* arg)的解答

本文通过C语言示例代码详细介绍了如何使用回调函数的方式创建进程。重点解释了process_create函数的实现原理及其内部如何利用fork函数来创建子进程,并通过传递func回调函数和arg参数给子进程。

process_create(pid_t* pid, void* func, void* arg)函数里的pid是func回调函数就是子进程执行的入口函数, arg是传递给func回调函数的参数。

这里用到了回调函数,关于回调函数的介绍可以参考这位大佬的博客:tingsking18老铁的博客

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>

typedef void (*FUNC)(char*) ;//定义一个函数指针FUNC

void func(char* arg){
    printf("%s,child pid is %d,father pid is %d\n",arg,getpid(),getppid());
    sleep(5);
    return;
}

void process_create(pid_t* pid, void* func, char* arg){
    *pid = fork();
    pid_t id;
    if( *pid < 0 ){
        perror("fork");
        return;
    }else if( *pid == 0 ){
        //child
        FUNC funct = (FUNC)func;
        //设置一个函数指针funct并将函数func的地址赋值给它。
        (*funct)(arg);//调用函数指针指向的函数,参数为arg.
        exit(0);
    }else{
        //father
        id = waitpid(-1,NULL,0); //父进程阻塞式等待
        printf("wait child successful!,child id is %d\n",id);
        return;
    }
    return;
}

int main(){
    pid_t pid;
    process_create(&pid, func, "haha");
    return 0;
}

//完成!
由于本人水平有限,上面的介绍可能不妥或者bug,欢迎发邮件到我的邮箱(Cyrus_wen@163.com)批评指正!

<think>好的,用户让我解释pthread_create函数各个参数的作用。首先,我需要确认用户对线程创建有一定的了解,可能他们正在学习多线程编程,或者在项目中遇到了相关问题。用户可能想知道每个参数的具体含义以及如何正确使用它们。 首先,pthread_create是POSIX线程库中的函数,用于创建新线程。我需要逐一解释每个参数。第一个参数是thread,这是一个指向pthread_t类型的指针,用来存储新创建线程的标识符。用户可能知道每个线程都有一个唯一的ID,这里就是通过这个参数返回的。 第二个参数是attr,指向pthread_attr_t的常量指针,用于设置线程属性。用户可能不太清楚线程属性具体包括哪些内容,比如栈大小、调度策略等。需要说明如果传入NULL的话,会使用默认属性,这对初学者来说比较重要,避免他们一开始就陷入复杂的配置中。 第三个参数是start_routine,这是一个函数指针,指向线程启动时执行的函数。用户需要知道这个函数必须符合特定的原型,即返回void*并接受一个void指针参数。可能需要举例说明如何编写这样的函数。 第四个参数是arg,传递给start_routine的参数。用户可能会疑惑如何传递多个参数,这时候需要说明可以通过传递结构体指针来解决这个问题。 接下来,我需要考虑用户可能的疑问点。例如,线程属性的具体使用场景,或者如何处理参数传递中的常见错误。此外,用户可能想知道线程创建后的执行流程,以及如何确保线程正确启动。 另外,用户可能对线程与进程的区别有一定了解,但需要明确pthread_createfork的区别,比如线程共享地址空间,而进程是独立的。不过这个问题可能不在当前问题范围内,但可以稍微提及。 需要确保解释清晰,避免使用过于专业的术语,但又要准确。例如,解释pthread_t时,可以说明它是线程的句柄,系统用它来标识线程。对于start_routine,强调函数指针的正确使用方式,比如参数和返回值的类型。 可能还需要给出一个简单的代码示例,展示如何使用pthread_create,比如创建一个线程并传递参数。但根据用户之前的示例格式,可能不需要代码块,但需要在相关问题中提到。 最后,用户可能想知道常见错误,比如参数传递错误,或者线程属性设置不当导致的问题。需要在注意事项中提醒这些点,帮助用户避免常见陷阱。</think>### **`pthread_create` 函数参数详解** `pthread_create` 是 POSIX 线程库中用于创建新线程的函数,其原型如下: ```c int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); ``` --- #### **1. 参数解析** | **参数** | **类型** | **作用** | **说明** | |--------------------|-------------------------|--------------------------------------------------------------------------|--------------------------------------------------------------------------| | **`thread`** | `pthread_t *` | 用于存储新线程的标识符(ID)。 | 线程创建成功后,系统会将线程 ID 写入 `*thread`。 | | **`attr`** | `const pthread_attr_t *`| 线程属性指针(如栈大小、调度策略、是否分离状态等)。 | 若传 `NULL`,则使用默认属性(适用于大多数场景)。 | | **`start_routine`**| `void *(*)(void *)` | 线程启动后执行的函数(入口函数)。 | 函数必须返回 `void*`,且接受一个 `void*` 参数(用于传递参数)。 | | **`arg`** | `void *` | 传递给 `start_routine` 的参数。 | 若需传递多个参数,可将参数封装为结构体并传递指针。 | --- #### **2. 参数详细说明** 1. **`thread`** - **类型**:`pthread_t` 是一个整数类型(通常是 `unsigned long`),用于唯一标识线程。 - **作用**:通过此参数获取线程 ID,后续可通过 `pthread_join` 或 `pthread_cancel` 操作目标线程。 - **示例**: ```c pthread_t tid; pthread_create(&tid, NULL, thread_func, NULL); ``` 2. **`attr`** - **线程属性**:通过 `pthread_attr_init` 和 `pthread_attr_setxxx` 系列函数配置,常见属性包括: - **栈大小**:`pthread_attr_setstacksize(&attr, size)`。 - **分离状态**:`pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)`。 - **调度策略**:`pthread_attr_setschedpolicy(&attr, SCHED_FIFO)`。 - **默认行为**:若传 `NULL`,线程属性由系统默认设定(如栈大小通常为 1MB 或更大)。 3. **`start_routine`** - **入口函数**:线程执行的函数,其原型必须为 `void* func(void*)`。 - **返回值**:线程退出时通过 `return` 或 `pthread_exit` 返回值传递给 `pthread_join`。 - **示例**: ```c void* thread_func(void* arg) { printf("Thread is running\n"); return NULL; } ``` 4. **`arg`** - **参数传递**:通过指针传递任意类型数据(如基本类型、结构体、数组等)。 - **多参数传递**:若需传递多个参数,可封装为结构体: ```c typedef struct { int id; char* name; } ThreadArgs; void* thread_func(void* arg) { ThreadArgs* args = (ThreadArgs*)arg; printf("ID: %d, Name: %s\n", args->id, args->name); return NULL; } ThreadArgs args = {1, "Worker"}; pthread_create(&tid, NULL, thread_func, &args); ``` --- #### **3. 返回值与错误处理** - **返回值**:成功返回 `0`,失败返回错误码(如 `EAGAIN` 表示资源不足)。 - **错误处理**: ```c int ret = pthread_create(&tid, NULL, thread_func, NULL); if (ret != 0) { fprintf(stderr, "Error creating thread: %s\n", strerror(ret)); exit(EXIT_FAILURE); } ``` --- #### **4. 典型使用场景** 1. **并发任务处理**:将耗时任务拆分到多个线程并行执行。 2. **异步 I/O 操作**:在后台线程中执行文件或网络读写。 3. **服务器模型**:为每个客户端连接创建独立线程处理请求。 --- #### **5. 注意事项** 1. **线程安全**:多个线程访问共享资源时需同步(如使用互斥锁 `pthread_mutex_t`)。 2. **资源泄漏**:线程退出后需调用 `pthread_join` 或设置分离状态(`PTHREAD_CREATE_DETACHED`),避免资源未回收。 3. **参数生命周期**:传递的 `arg` 若为局部变量,需确保线程访问时变量未销毁(如使用动态内存分配)。 --- #### **6. 完整示例** ```c #include <pthread.h> #include <stdio.h> #include <stdlib.h> void* thread_func(void* arg) { int* id = (int*)arg; printf("Thread ID: %d\n", *id); return NULL; } int main() { pthread_t tid; int thread_id = 100; int ret = pthread_create(&tid, NULL, thread_func, &thread_id); if (ret != 0) { perror("pthread_create"); exit(EXIT_FAILURE); } pthread_join(tid, NULL); // 等待线程结束 return 0; } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值