1. 函数
#include <pthread.h>
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void*), void *restrict arg);
参数:
- thread 为线程id的容器, 通过类型可知为传地址即(&pthread_id)
- attr 线程地址一般用NULL
- 为线程操作函数function,即线程执行代码(函数名传递方式)
- arg为function 操作所需要的参数(可自定义)
2. 1 代码(传递基本类型)
#include<stdio.h>
#include<pthread.h>
void *function(void *arg)
{
int n=(int)arg; //参数强制转换成所需要的类型
for(int i=1;i<=n;i++)
{
printf("%lx run %d\n",pthread_self(),i);
sleep(1);//微秒
}
return (void *)0; //细节,线程主动终止
}
int main()
{
pthread_t rabbit,turtle; //线程标志符
int err; //错误返回
//创建线程
if((err=pthread_create(&rabbit,NULL,function,(void *)50))!=0)
{
perror("pthread_create error");
}
if((err=pthread_create(&turtle,NULL,function,(void *)50))!=0)
{
perror("pthread_create error");
}
//主线程等待子线程结束方可执行下面的程序
pthread_join(rabbit,NULL);
pthread_join(turtle,NULL);
//主线程id
printf("control thread id: %lx\n",pthread_self());
printf("finished....\n");
return 0;
}
注:
程序编译时记得加入 -lpthread 选项
2.2 代码(传递结构体)
#include<stdio.h>
#include<pthread.h>
#include<math.h>
typedef struct
{
char name[20]; //线程名
int time; //线程延时时间
int start; //线程开始
int end; //线程结束
}data;
void *function(void *arg)
{
data *get=(data *)arg; //强制转换成结构体指针形式
for(int i=get->start;i<=get->end;i++)
{
printf("%s(%lx) runnning %d\n",get->name,pthread_self(),i);
usleep(get->time);//微秒
}
return (void *)0; //线程主动终止
}
int main()
{
pthread_t rabbit,turtle; //线程标志符
int err; //错误返回
data r_a={
"rabbit",(int)(drand48()*1000000),20,50
};
data t_a={
"turtle",(int)(drand48()*1000000),10,60
};
//创建线程
if((err=pthread_create(&rabbit,NULL,function,(void *)&r_a))!=0) //传地址
{
perror("pthread_create error");
}
if((err=pthread_create(&turtle,NULL,function,(void *)&t_a))!=0) //传地址
{
perror("pthread_create error");
}
pthread_join(rabbit,NULL);
pthread_join(turtle,NULL);
//主线程id
printf("control thread id: %lx\n",pthread_self());
printf("finished....\n");
return 0;
}
3. 问题
3.1 多线程共享哪些? 独占哪些?
答: 由于同一进程的多个线程共享同一地址空间,因此Text、Segment、Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境:
- 文件描述符表
- 每种信号的处理方式( SIG_IGN 、 SIG_DFL 或者自定义的信号处理函数)
- 当前工作目录
- 用户id和组id
但有些资源是每个线程各有一份的(即独占的):
- 线程id
- 上下文,包括各种寄存器的值、程序计数器和栈指针
- 栈空间
- errno 变量
- 信号屏蔽字
- 调度优先级