各线程共享的进程资源和环境
- 进程同一地址空间
- 同一进程定义的函数和全局变量
- 文件描述符表
- 每种信号的处理方式(
SIG_IGN
、SIG_DFL
或者自定义的信号处理函数) - 当前工作目录
- 用户id和组id
线程各自独立的资源
- 线程id
- 上下文,包括各种寄存器的值、程序计数器和栈指针
- 栈空间
errno
变量- 信号屏蔽字
- 调度优先级
1.创建线程
#include <stdio.h>
#include <stdlib.h>
//线程所需要的头文件
#include <pthread.h>
//getpid需要的头文件
#include <unistd.h>
//线程编译需要加上-lpthread
int temp = 0;
void printids(char *s)
{
pid_t pid;
pthread_t tid;
pid = getpid();
tid = pthread_self();//获取当前线程id
//由于pthread_t并不是一个整型,所以需要做强制类型转换
printf("%s pid:%d, tid:%u\n", s, pid, (unsigned int)tid);
}
//线程处理函数
void *thread_handler(void *arg)
{
static int value = 0;
temp++; //线程间共享全局变量、局部变量、函数
value++;
printf("%s value:%d, temp:%d\n", (char*)arg, value, temp);
printids(arg);
return NULL;
}
int main(void)
{
pthread_t tid;
int err;
/*
* 返回线程id
* 线程属性设置
* 线程处理函数
* 线程处理函数参数
*/
err = pthread_create(&tid, NULL, thread_handler, "new_thread1");
//pthread_create失败返回错误码
if (err != 0) {
//由于pthread_create的错误码不保存在errno中,因此不能直接用perror()打印错误信息
fprintf(stderr, "pthread_create1\n");
exit(1);
}
printf("create tid %u\n", (unsigned int)tid);
err = pthread_create(&tid, NULL, thread_handler, "new_thread2");
//pthread_create失败返回错误码
if (err != 0) {
//由于pthread_create的错误码不保存在errno中,因此不能直接用perror()打印错误信息
fprintf(stderr, "pthread_create2\n");
exit(1);
}
printf("create tid %u\n", (unsigned int)tid);
printids("main_thread");
sleep(2);//预留线程调度的时间
return 0;
}
2.终止线程
只终止某个线程可以有三种方法:
- 从线程函数
return
。这种方法对主线程不适用,从main
函数return
相当于调用exit
。 - 一个线程可以调用
pthread_cancel
终止同一进程中的另一个线程。 - 线程可以调用
pthread_exit
终止自己。
1)终止某个线程
#include <pthread.h>
void pthread_exit(void *value_ptr);
/*
成功返回0,失败返回错误号
*/
2)自身线程挂起