pthread_create如何传递多个参数

本文介绍了一种在pthread_create函数中使用结构体封装多个参数的方法,并提供了详细的代码示例。这种方法可以有效解决多参数传递问题,同时保持接口的简洁性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://zhidao.baidu.com/question/315398992.html

涉及多参数传递给线程的,都需要使用结构体将参数封装后,将结构体指针传给线程

定义一个结构体
struct mypara
{
       var para1;//参数1
       var para2;//参数2
}
将这个结构体指针,作为void *形参的实际参数传递
struct mypara pstru;
pthread_create(&ntid, NULL, thr_fn,& (pstru));
函数中需要定义一个mypara类型的结构指针来引用这个参数 
void *thr_fn(void *arg)
{
       mypara *pstru;
       pstru = (* struct mypara) arg;
       pstru->para1;//参数1
       pstru->para2;//参数2

}

pthread_create函数接受的参数只有一个void *型的指针,这就意味着你只能通过结构体封装超过一个以上的参数作为一个整体传递。这是pthread_create函数的接口限定的,别人已经明确表明我只接受一个参数,你硬要塞给他两个肯定会出错了。所以通过结构体这种组合结构变通一下,同样实现了只通过一个参数传递,但通过结构指针对结构数据成员的引用实现多参数的传递

这种用结构体封装多参数的用法不仅仅用在pthread_create函数中,如果你自己设计的函数需要的参数很多〉=5个以上,都可以考虑使用结构体封装,这样对外你的接口很简洁清晰,你的函数的消费者使用起来也很方便,只需要对结构体各个成员赋值即可,避免了参数很多时漏传、误传(参数串位)的问题

结构体内包含结构体完全没有问题,很多应用都这么使用


举例如下:

http://wenku.baidu.com/view/48a302ed6294dd88d0d26b73.html

  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<pthread.h>  
  4. #include<errno.h>  
  5. #include<unistd.h>  
  6.   
  7. typedef void* (*fun)(void*);    
  8.   
  9. static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  
  10. static pthread_cond_t recv_over = PTHREAD_COND_INITIALIZER;  
  11. static pthread_cond_t decode_over = PTHREAD_COND_INITIALIZER;  
  12. static pthread_cond_t play_over = PTHREAD_COND_INITIALIZER;  
  13.   
  14. void* receive(void*);  
  15. void* decode(void*);  
  16. void* play(void*);  
  17.   
  18. pthread_t tdec, tplay, trecv;  
  19.   
  20. struct mypara   
  21. {   
  22.     int thread_id;  
  23.     char *thread_name;   
  24. };  
  25.   
  26. int main(int argc, char** argv)  
  27. {  
  28.     struct mypara para;  
  29.     para.thread_id = 1;  
  30.     para.thread_name = "recv";  
  31.       
  32.     int t1 = 0, t2 = 0, t3 = 0;  
  33.     t1 = pthread_create(&trecv, NULL, receive,& (para));  
  34.     if(t1 != 0)  
  35.         printf("Create thread receive error!\n");  
  36.       
  37.     t2 = pthread_create(&tdec, NULL, decode, NULL);  
  38.     if(t2 != 0)  
  39.         printf("Create thread decode error!\n");  
  40.   
  41.     t3 = pthread_create(&tplay, NULL, play, NULL);  
  42.     if(t3 != 0)  
  43.         printf("Create thread play error!\n");  
  44.   
  45.     pthread_join(trecv, NULL);  
  46.     pthread_join(tdec, NULL);  
  47.     pthread_join(tplay, NULL);  
  48.     printf("leave main\n");  
  49.     exit(0);      
  50. }  
  51.   
  52. void* receive(void* arg)  
  53. {  
  54.     printf("Start receive\n");  
  55.     int i = 0;  
  56.     char *s = NULL;  
  57.   
  58.     struct mypara *recv_para;  
  59.     recv_para = (struct mypara *)arg;  
  60.     i = (*recv_para).thread_id;  
  61.     s = (*recv_para).thread_name;  
  62.     printf("NO : %d Name : %s\n",i,s);  
  63.       
  64.     sleep(2);  
  65.     pthread_mutex_lock(&mutex);  
  66.     while (1)  
  67.     {  
  68.         printf("Receiving...\n");  
  69.         sleep(1);  
  70.         pthread_cond_signal(&recv_over);  
  71.         pthread_cond_wait(&decode_over, &mutex);   
  72.     }  
  73.     printf("End receive\n");  
  74.     pthread_exit(0);  
  75. }  
  76.   
  77. void* decode(void* arg)  
  78. {  
  79.     printf("Start decode\n");  
  80.       
  81.     while (1)  
  82.     {  
  83.         pthread_cond_wait(&recv_over, &mutex);   
  84.         printf("Decoding...\n");  
  85.         sleep(1);  
  86.         pthread_cond_broadcast(&decode_over);   //inform player ready to play  
  87.     }  
  88.     printf("End decode\n");  
  89.     pthread_exit(0);  
  90. }  
  91.   
  92.   
  93. void* play(void* arg)  
  94. {  
  95.     int ret;  
  96.     printf("Start play\n");  
  97.   
  98.     while(1)  
  99.     {  
  100.         pthread_cond_wait(&decode_over, &mutex); //wait the signal from decoder  
  101.         printf("Playing...\n");  
  102.         sleep(1);  
  103.     }  
  104.     pthread_mutex_unlock(&mutex);  
  105.     printf("End play\n");  
  106.     pthread_exit(0);  
  107. }  


<think>嗯,用户问的是如何使用pthread_create函数传递参数给data_collection_thread线程函数。我需要仔细解释这个过程。首先,pthread_create的第四个参数就是用来传递参数的,用户现在用的是NULL,所以应该把要传的数据放在那里。不过用户可能不太清楚具体怎么操作,可能需要分步骤说明。 首先,我应该回忆一下pthread_create的函数原型,确认参数的位置。函数原型是int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg)。所以第四个参数arg就是传递给线程函数的参数,类型是void*,所以用户需要把数据转换成这个类型。 用户当前的例子是pthread_create(&tid, NULL, data_collection_thread, NULL);,这里最后一个参数NULL,说明没有传参。要传参的话,需要构造一个参数,比如结构体,然后传递它的指针。这时候需要提醒用户注意数据的作用域和生命周期,确保线程在使用时数据仍然有效,否则可能会出现悬空指针的问题。 可能需要举例说明如何定义一个结构体,填充数据,然后将结构体指针作为参数传递。同时,在线程函数内部,需要将void*转换回原来的结构体类型,然后使用里面的数据。还要注意,如果传递的是局部变量的地址,必须确保线程在访问时变量没有被销毁,比如在函数返回后,局部变量就不存在了,这时候线程访问会导致未定义行为。因此,建议使用动态分配的内存或者全局变量。 另外,可能需要提到,如果传递的是基本类型,比如int,可以直接将int转换为void*,但要注意在64位系统上可能会有问题,因为int和指针的大小可能不同。这时候更安全的做法是动态分配内存,传递指针,并在使用后释放。 还要注意线程安全,多个线程访问同一数据时需要同步机制,比如互斥锁,但用户的问题可能还没涉及到这方面,暂时不需要深入。 总结步骤应该是:定义数据结构,填充数据,传递指针,在线程函数中转换类型,使用数据,最后释放内存(如果是动态分配的)。同时提醒注意事项,比如数据生命周期和类型转换的安全性。 可能用户是新手,所以需要详细解释每个步骤,并给出示例代码,这样更容易理解。同时,要使用中文,保持口语化,避免使用专业术语过多,必要时解释术语。</think>在Linux多线程编程中,使用`pthread_create`传递参数给线程函数的关键在于第四个参数。以下是具体实现步骤和注意事项: 1. **函数原型理解**: ```c int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); // 这是传参的关键参数 ``` 2. **参数传递示例**(假设要传递结构体): ```c // 1.定义数据结构 typedef struct { int sensor_id; int sampling_rate; } ThreadParams; // 2.创建参数实例(注意生命周期) ThreadParams params = { .sensor_id = 1, .sampling_rate = 100 }; // 3.创建线程时传递参数地址 pthread_create(&tid, NULL, data_collection_thread, &params); // 4.在线程函数中解析参数 void* data_collection_thread(void* arg) { ThreadParams* params = (ThreadParams*)arg; printf("Sensor ID: %d\n", params->sensor_id); // ...其他处理... return NULL; } ``` 3. **注意事项**: - ✅ **内存管理**:如果参数需要跨函数传递,应使用动态内存: ```c ThreadParams* params = malloc(sizeof(ThreadParams)); params->sensor_id = 2; pthread_create(&tid, NULL, thread_func, params); // 在线程函数结束时记得 free(params) ``` - ⚠️ **生命周期警告**:绝对不要传递局部变量的地址: ```c void bad_example() { int local_var = 10; // 局部变量 pthread_create(&tid, NULL, thread_func, &local_var); // 危险!函数返回后局部变量失效 } ``` - 🔧 **基础类型传参**(仅限兼容指针大小的类型): ```c int value = 42; pthread_create(&tid, NULL, thread_func, (void*)(intptr_t)value); // 在线程函数中: int received = (int)(intptr_t)arg; ``` 4. **完整示例**: ```c #include <pthread.h> #include <stdio.h> #include <stdlib.h> typedef struct { char* device_name; int timeout_ms; } ThreadConfig; void* data_thread(void* arg) { ThreadConfig* cfg = (ThreadConfig*)arg; printf("Collecting from %s, timeout %dms\n", cfg->device_name, cfg->timeout_ms); free(cfg); // 释放动态分配的内存 return NULL; } int main() { pthread_t tid; // 动态分配配置参数 ThreadConfig* config = malloc(sizeof(ThreadConfig)); config->device_name = "USB_Sensor_01"; config->timeout_ms = 500; if(pthread_create(&tid, NULL, data_thread, config)) { perror("Thread creation failed"); free(config); // 创建失败时也要释放 } pthread_join(tid, NULL); return 0; } ``` 关键要点: 1. 使用结构体封装复杂参数 2. 优先使用动态内存分配(malloc) 3. 在线程函数中及时释放内存 4. 注意指针类型的强制转换规范 5. 保证参数在生命周期有效性 这种参数传递方式在实时数据采集、多设备控制等场景非常常见,合理使用可以构建高效的多线程数据采集系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值