pthread_create
函数创建新线程,并使用
pthread_join
等待线程完成。
在Linux环境下,使用C语言进行多线程编程是一种提高程序运行效率和资源利用率的重要手段,通过创建多个线程,可以同时执行多个任务,从而充分利用系统资源,提升程序性能,下面将详细介绍如何在Linux C中运行多线程,包括线程的创建、管理以及同步机制。
多线程(multithreading)是指从软件或者硬件上实现多个线程并发执行的技术,具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能,具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理或同时多线程处理器。
线程在其生命周期中会经历以下几种状态:
1、就绪态:线程已经具备运行条件,等待被调度器选中运行。
2、运行态:线程正在CPU上执行。
3、阻塞态:线程由于等待某些条件(如I/O操作、互斥锁释放等)而无法继续执行。
4、终止态:线程完成执行或被其他线程取消后的状态。
线程函数是线程创建后进入运行态所要执行的函数,它通常是一个全局函数或类的静态函数,并在创建线程时作为参数传入,线程创建成功后,系统会为线程分配唯一的ID作为标识。
在Linux环境下,多线程编程主要依赖于POSIX线程库(pthread),以下是一些常用的多线程API函数:
pthread_create():创建新线程。
pthread_exit():结束调用线程并返回指定值。
pthread_join():等待指定线程结束。
pthread_mutex_t:定义互斥锁。
pthread_mutex_init():初始化互斥锁。
pthread_mutex_lock():加锁。
pthread_mutex_unlock():解锁。
pthread_cond_t:定义条件变量。
pthread_cond_wait():等待条件变量。
pthread_cond_signal():发出条件信号。
以下是一个使用POSIX线程库实现多线程矩阵乘法的示例代码:
#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <sys/time.h> #define LEN 1000 #define MAXNUM 1000 #define MAXTHREADNUM 16 long long matrix1[LEN][LEN] = {0}; long long matrix2[LEN][LEN] = {0}; long long sum[MAXTHREADNUM] = {0}; long long ans = 0; long long getCurrentTime() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * 1000 + tv.tv_usec / 1000; } void genMatrix(char *file) { FILE *fp = fopen(file, "w"); srand(time(NULL)); for (int i = 0; i < LEN; i++) { for (int j = 0; j < LEN; j++) { int random = rand() % MAXNUM; fprintf(fp, "t%d", random); } fprintf(fp, " "); } fclose(fp); } void getMatrix(long long matrix[LEN][LEN], char *file) { FILE *fp = fopen(file, "r"); for (int i = 0; i < LEN; i++) { for (int j = 0; j < LEN; j++) { fscanf(fp, "t%lld", &matrix[i][j]); } char tmp; fscanf(fp, "%c", &tmp); } } int threadNum; void* runner(void *p) { int pid = *(int*)p; long long sumT = 0; for (int i = pid; i < LEN; i += threadNum) { for (int j = 0; j < LEN; j++) { for (int k = 0; k < LEN; k++) { sumT += matrix1[i][k] * matrix2[k][j]; } } } sum[pid] = sumT; free((int *)p); pthread_exit(NULL); } void multiThread(int num) { threadNum = num; long long clock1 = clock(); long long time1 = getCurrentTime(); pthread_t id[MAXTHREADNUM]; for (int i = 0; i < threadNum; i++) { int *p = (int *)malloc(sizeof(int)); *p = i; pthread_create(&id[i], NULL, runner, p); } ans = 0; for (int i = 0; i < threadNum; i++) { pthread_join(id[i], NULL); ans += sum[i]; } long long clock2 = clock(); long long time2 = getCurrentTime(); printf("Multi Thread %d: ", num); printf("Ans =t%lld Clock time =t%lldms Unix time =t%lldms ", ans, (clock2 clock1) / 1000, time2 time1); } int main() { char name1[50] = "matrix1.txt"; char name2[50] = "matrix2.txt"; FILE *fp = fopen(name1, "r"); if (fp == NULL) { genMatrix(name1); } else { fclose(fp); } fp = fopen(name2, "r"); if (fp == NULL) { genMatrix(name2); } else { fclose(fp); } getMatrix(matrix1, name1); getMatrix(matrix2, name2); for (int i = 1; i <= 16; i++) { multiThread(i); } }
Q1: 如何在Linux C中使用多线程提高程序性能?
A1: 在Linux C中使用多线程可以通过POSIX线程库(pthread)来实现,需要包含必要的头文件,如<pthread.h>
,使用pthread_create()
函数创建新线程,并指定线程要运行的函数,为了确保线程安全,可以使用互斥锁(mutex)和条件变量(cond)来控制对共享资源的访问,使用pthread_join()
等待线程完成,通过合理分配任务给多个线程,可以充分利用多核CPU的优势,从而提高程序的性能。
Q2: 如何处理多线程中的race condition问题?
A2: Race condition是指在多线程环境中,多个线程同时读写共享数据时产生的竞争现象,为了解决这个问题,可以使用互斥锁(mutex)来保护共享资源,当一个线程需要访问共享资源时,它必须先获得互斥锁;访问完成后,再释放互斥锁,这样可以确保在任何时刻只有一个线程能够访问共享资源,从而避免race condition的发生,还可以使用条件变量来协调线程之间的执行顺序,确保数据的一致性和正确性。