线程常用API、线程传参


pthread_xxx 错误检查

  1. 传统的一些函数是,成功返回0,失败返回-1,并且对全局变量errno赋值以指示错误。
  2. pthreads函数出错时不会设置全局变量errno(而大部分其他POSIX函数会这样做)。而是将错误代码通过返回值返回
  3. pthreads同样也提供了线程内的errno变量,以支持其它使用errno的代码。
  4. 对于pthreads函数的错误,建议通过返回值判定,因为读取返回值要比读取线程内的errno变量的开销更小对于pthreads函数的错误

pthread_t pthread_self(void);   返回线程ID

int pthread_create(
  pthread_t *thread,  //传出参数:线程ID=unsigned long
  const pthread_attr_t *attr,  //设置线程的属性,attr为NULL表示使用默认属性
  void *(*start_routine) (void *),  //线程回调函数
  void *arg  //线程回调函数的参数
);        
成功,返回0;失败,返回错误号
注解1perror()不能使用该函数打印错误信息,而是使用strerror(ret),打印错误码
注解2:主线程先退出,子线程会被强制结束

int pthread_equal(pthread_t t1, pthread_t t2);
    实际上该函数很少用,线程ID是unsigned long数据类型,可以直接对比两个值是否相等来判断两个线程的ID是否相等,进而判断是否为同一个线程。

int pthread_join(pthread_t thread, void **retval); ① 使主线程等待线程ID=thread子线程执行完后,主线程才退出;② 通过pthread_exit / return获取子线程的传来的数据

pthread_detach:使线程在创建后脱离主线程,脱离的线程在终止时,所有的相关资源将会被自动释放。

void pthread_exit(void *retval);    // 参数retval不要指向一个局部变量


知识点1—向线程函数传递参数

情况1:int类型的实参(直接强转就OK)

void* myfunc(void* arg){ //形参 arg
  //直接将arg强制转换成int就可以使用
  printf("%dth child thread id = %lu\n",(int)arg,pthread_self());   // (int)arg
} 
int main(){    
  pthread_t tid;            
  int i;       
  pthread_create(&tid,NULL,myfunc,(void*)i); // 实参 (void*)i
} 

情况2:非int类型的实参
① 在main线程中,malloc一个空间保存实参
② 在子线程中,强转后使用,使用完成之后free释放资源

知识点2—线程函数向主线程函数传回数据

    在线程函数中,使用pthread_exit函数,可以将thread_func中的非局部变量传递给主线程;主线程中使用pthread_join函数接收该非局部变量的值;pthread_join函数的第二个参数void *retval将会接收到pthread_exit(void retval)传回来的值。

Q:pthread_exit和pthread_join函数是怎么进行数据传递的?
答:调用pthread_join(tid,&ptr)函数后,ptr指针与pthread_exit的参数指向同一块内存

代码案例—返回线程函数中的值

struct node{   
 int data;    
 char buf[1024]; 
};
void* thread_func(void* arg){  
 struct node* nd=(struct node*)malloc(sizeof(struct node));  //非局部变量 
 nd->data=100;
 strcpy(nd->buf,"Thunder");   
 //将线程函数中的非局部变量值,通过pthread_exit/return的方式“甩给”主线程         
 //pthread_exit(nd); //方法1
 return nd; //方法2
}  
int main(){    
 pthread_t tid;  
 int ret=pthread_create(&tid,NULL,thread_func,NULL);          
 if(ret!=0)   
   printf("ret=%d,error=%s\n",ret,strerror(ret));

 void* retval=NULL;           
 pthread_join(tid,&retval); //主线程接收线程函数中“甩出来”的值   
 printf("%d,%s\n",((struct node*)retval)->data,((struct node*)retval)->buf);     
}   
### 如何在 JMeter 的线程组中设置和传递参数 #### 设置全局变量以便跨线程组使用 为了使不同的线程组能够共享同一个 token 或其他类型的参数,在第一个线程组内获取该参数之后,应该将其转换为全局变量。这可以通过 `__setProperty` 函数实现,它允许将局部变量提升至整个测试计划层面作为属性存在。 ```java // 将登录返回的token保存为全局属性 ${__setProperty(auth, ${loginToken})} ``` 一旦设置了这样的全局属性,在后续任何地方都可以通过 `${__property}` 来访问这个值[^2]。 #### 使用 JSON 提取器配合 Beanshell 后处理器 当涉及到复杂的 API 响应解析时,比如从 JSON 格式的响应体里抽取特定字段并把它设为全局可用,则可以在 HTTP 请求后面附加两个组件: 1. **JSON Extractor**: 定义要提取的数据路径以及目标变量名; 2. **Beanshell PostProcessor**: 利用上述定义好的本地变量,并借助于 `props.put()` 方法把其变为全局可读写的属性。 ```groovy import org.apache.jmeter.util.JMeterUtils; // 获取名为 'estimateId' 的 JSON 提取结果,并存储为全局属性 vars.get('estimateId'); // 这是从前面HTTP请求得到的结果 JMeterUtils.setProperty("global_estimate_id", vars.get('estimateId')); ``` 这里展示了如何先利用 JSON 提取工具定位所需数据项,再经由 BeanShell 脚本进一步处理使之成为真正意义上的全局资源[^4]。 #### 实际应用案例展示 假设有一个场景是在首次认证成功后获得了一个有效的 session ID (`auth_token`) ,那么就可以按照如下方式操作: - 在首个线程组内的 POST 登录接口处配置好 JSON 提取规则以捕获此令牌。 - 接着在同一级添加一个 BeanShell 处理单元执行类似于下面这段简单的 Java 语句来完成最终赋值动作: ```java props.put("shared_auth_token","${auth_token}"); ``` 对于第二个乃至更多个依赖于此凭证信息继续工作的线程组而言,只需要简单地插入相应位置即可随时取出之前设定过的公共财产: ```bash ${__P(shared_auth_token)} ``` 这样就实现了多个独立运行但又彼此关联的任务之间的无缝衔接[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值