pthread_create()函数参数详解和传参的使⽤
题外话:
⽤的vscode编译的程序。发现⼀个问题,就是编译的时候提⽰没有gcc,但是应该是安装了的。打开命令端,输⼊gcc -v,提⽰没有gcc。
因为安装了qt。默认的就有gcc,所以就打开qt的安装路径下C:\Qt\Qt5.12.4\Tools\mingw730_64\bin,路径下⽂件如下图所⽰
然后直接把该路径添加到环境变量,就可以使⽤gcc 和g++了
贼有意思,gcc也能编译,g++也能编译。
在linux下通过gcc编译c程序,g++编译c++程序,另外就是也没有加-lpthread连接线程库就编译通过了。
sleep函数使⽤的头⽂件<unistd.h>也可以编译通过,也就是说,并没有使⽤windows的库。
正题:
pthread_create是UNIX环境创建线程函数
头⽂件  #include<pthread.h>
函数声明   int pthread_create(pthread_t*restrict tidp,const pthread_attr_t
restrict_attr,void(start_rtn)(void),void *restrict arg);
返回值   若成功则返回0,否则返回出错编号   返回成功时,由tidp指向的内存单元被设置为新创建线程的线程ID。attr参数⽤于制定各种不同的线程属性。新创建的线程从start_rtn函数的地址开始运⾏,该函数只有⼀个万能指针参数arg,如果需要向start_rtn函数传递的参数不⽌⼀个,那么需要把这些参数放到⼀个结构中,然后把这个结构的地址作为arg的参数传⼊。   linux下⽤C开发多线程程
序,Linux系统下的多线程遵循POSIX线程接⼝,称为pthread。   由 restrict 修饰的指针是最初唯⼀对指针所指向的对象进⾏存取的⽅法,仅当第⼆个指针基于第⼀个时,才能对对象进⾏存取。对对象的存取都限定于基于由 restrict 修饰的指针表达式中。 由 restrict 修饰的指针主要⽤于函数形参,或指向由 malloc() 分配的内存空间。restrict 数据类型不改变程序的语义。 编译器能通过作出 restrict 修饰的指针是存取对象的唯⼀⽅法的假设,更好地优化某些类型的例程。 参数   第⼀个参数为指向线程
标识符的指针。   第⼆个参数⽤来设置线程属性。   第三个参数是线程运⾏函数的起始地址。   最后⼀个参数是运⾏函数的参数。   另外,在编译时注意加上-lpthread参数,以调⽤静态链接库。因为pthread并⾮Linux系统的默认库 ⽰例   打印线程 IDs
#include<pthread.h>
  #include<stdlib.h>
  #include<stdio.h>
  #include<unistd.h>
  #include<string.h>
  pthread_t ntid;
  void printids(const char*s)
  {
  pid_t pid;
  pthread_t tid;
  pid =getpid();
  tid =pthread_self();
  printf("%s pid %u tid %u (0x%x)\n", s,
  (unsigned int)pid,(unsigned int)tid,(unsigned int)tid);
  }void*thr_fn(void*arg)
  {
  printids("new thread: ");
  return((void*)0);
  }
  int main(void)
  {
  int err;
  err =pthread_create(&ntid,NULL, thr_fn,NULL);
  if(err !=0)
linux下的sleep函数  printf("can't create thread: %s\n",strerror(err));
  printids("main thread:");
  sleep(1);
  exit(0);
  }
  $ gcc main.c -lpthread
  $ ./a.out
向线程函数传递参数详解:
向线程函数传递参数分为两种:
(1)线程函数只有⼀个参数的情况:直接定义⼀个变量通过应⽤传给线程函数。
例⼦:
#include<iostream>
#include<pthread.h>
using namespace std;
pthread_t thread;
void fn(void*arg)
{
int i =*(int*)arg;
cout<<"i = "<<i<<endl;
return((void*)0);
}
int main()
{
int err1;
int i=10;
err1 =pthread_create(&thread,NULL, fn,&i);
pthread_join(thread,NULL);
}
2、线程函数有多个参数的情况:这种情况就必须申明⼀个结构体来包含所有的参数,然后在传⼊线程函数,具体如下:
例⼦:
⾸先定义⼀个结构体:
struct  parameter
{
int size,
int count;
};
然后在main函数将这个结构体指针,作为void *形参的实际参数传递
struct parameter arg;
通过如下的⽅式来调⽤函数:
pthread_create(&ntid,NULL, fn,&(arg));
函数中需要定义⼀个parameter类型的结构指针来引⽤这个参数
void fn(void*arg)
{
int i =*(int*)arg;
cout<<"i = "<<i<<endl;
return((void*)0);
}
void thr_fn(void*arg)
{
struct parameter *pstru;
pstru =(struct parameter *) arg;
然后在这个函数中就可以使⽤指针来使⽤相应的变量的值了。
}
**
具体实例
**
主要解决以下三个问题
1.普通传参(只传⼀个参数)
2.结构体传参(传多个参数)
1. 普通传参(只传⼀个参数)
函数功能介绍,主线程⼀个while循环,等待变量的值,如果等于10就打印⼀句话。新创建的线程⾸先拿到传递过来的参数,然后再给参数赋值(相当于主线程已经等到了要的值)
#include<stdio.h>
#include<pthread.h>
#include<time.h>
#include<unistd.h>
//int sum = 0;
void*test(void*arg)
{
printf("arg= %d\n",*(int*)arg);
//int sum = *(int *)arg;
int temp_run=1;
temp_run =*(int*)arg;
printf("tem_run= %d\n",temp_run);
*(int*)arg =10;
temp_run =*(int*)arg;
//sum = sum + 1;
while(temp_run){
temp_run --;
if(temp_run ==2)
printf("tem_run= %d\n",temp_run);
}
}
int main()
{
pthread_t pthread_id;
int sum =0;//局部变量,在main函数中,main没有结束,就不会释放。main是⼀个进程吗?⼀次执⾏过程
int run =1;
int time =10;
int ret =-1;
/*if(pthread_create(&pthread_id,NULL,test,&sum) != 0)
printf("create error\n");
*/
ret =pthread_create(&pthread_id,NULL,test,&sum);
printf("ret = %d\n",ret);
while(run)
{
/*
if(sum != time)
sum++;
*/
if(sum == time)
{
printf("------run end------\n");
run =0;
}
}
/
/pthread_create(&pthread_id,NULL,test,&sum);//在while循环后创建线程,能执⾏到创建这⼀句吗?
//sleep(5);//没有打印出来线程⾥的消息,是因为主线程已经结束了。睡眠五秒可以解决。另外⼀般都是调⽤ptread_join()pthread_join(pthread_id,NULL);//阻塞等待当前线程
printf("sum=%d,run=%d,time=%d\n",sum,run,time);
pthread_exit(&pthread_id);//结束当前线程,释放私有资源
return0;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。