本文已参与「新人创作礼」活动,一起开启掘金创作之路。
目录
一、线程的概念
线程就是一个正在运行的函数,不同的平台有不同的线程标准,posix 线程是一套标准,而不是实现;
线程标识:pthread_t,不要用%d直接打印,如果想判断线程 id 可以用 pthread_equal 非零表示相等,pthread_self 返回当前线程号;
二、线程的创建
pthread_create(pthread_t*, const pthread_attr_t,void (func)(void), void*) 创建线程
创建失败直接返回 errorno ,线程的调度取决于调度器策略
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
static void* fun(void *p) {
printf("create thread : %lu\n", (unsigned long)(pthread_self()));
pthread_exit(NULL);
}
int main() {
pthread_t tid;
puts("Begin!");
int err = pthread_create(&tid, NULL, fun, NULL);
if(err) {
fprintf(stderr, "pthread create failed : %s\n", strerror(err));
exit(0);
}
//sleep(1);
pthread_join(tid, NULL);
puts("End!");
exit(0);
}
三、线程的终止与栈清理
1、线程终止
线程从启动例程返回,返回值就是线程的退出码,线程可以被同一进程中的其他线程取消;
线程退出调用 pthread_exit() 函数。
2、栈的清理
pthread_cleanup_push();
pthread_cleanup_pop();
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
static void cleanup_func(void *p) {
puts(p);
}
static void* fun(void *p) {
printf("create thread : %lu\n", (unsigned long)(pthread_self()));
pthread_cleanup_push(cleanup_func, "cleanup1"); //相当于宏定义,必须成对出现
pthread_cleanup_push(cleanup_func, "cleanup2");
pthread_cleanup_push(cleanup_func, "cleanup3");
puts("push over!");
pthread_cleanup_pop(1);
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
pthread_exit(NULL);
}
int main() {
pthread_t tid;
puts("Begin!");
int err = pthread_create(&tid, NULL, fun, NULL);
if(err) {
fprintf(stderr, "pthread create failed : %s\n", strerror(err));
exit(0);
}
//sleep(1);
pthread_join(tid, NULL);
puts("End!");
exit(0);
}
四、线程取消
使用 pthread_cancel() 有两种状态:允许和不允许
允许取消又分为:异步cancel、推迟cancel;
cancel点:posix定义的cancel点,都是可能引发阻塞的系统调用
pthread_setcancelstate():设置是否允许取消
pthread_setcanceltype():设置取消方式
pthread_testcancel():本函数什么都不做,就是一个取消点
五、线程分离
使用 pthread_detach(),线程分离后,主线程不再管负责收尸工作。
六、线程同步
互斥量:
pthread_mutex_init()
pthread_mutex_destory()
pthread_mutex_lock()
pthread_mutex_trylock()
pthread_mutex_unlock()
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#define THREADNUM 20
#define FNAME "/home/thread/temp.out"
#define LINESIZE 1024
static pthread_mutex_t ptu = PTHREAD_MUTEX_INITIALIZER;
static void* func(void *i) {
char buf[LINESIZE];
FILE* fp;
fp = fopen(FNAME, "r+");
if (fp == NULL) {
perror("fopen()");
exit(1);
}
pthread_mutex_lock(&ptu);
fgets(buf, LINESIZE, fp);
//sleep(1);
fseek(fp, 0, SEEK_SET);
fprintf(fp, "%d\n", atoi(buf) + 1);
fclose(fp);
pthread_mutex_unlock(&ptu);
pthread_exit(NULL);
}
int main() {
pthread_t tid[THREADNUM];
int err;
for (int i = 0; i < THREADNUM; i++) {
err = pthread_create(tid+i, NULL, func, NULL);
if (err) {
fprintf(stderr, "pthread_create() : %s", strerror(err));
exit(1);
}
}
for (int i = 0; i < THREADNUM; i++) {
pthread_join(tid[i], NULL);
}
pthread_mutex_destroy(&ptu);
exit(0);
}