多线程函数详解 Multithreading

tech2026-06-14  3

文章目录

一、pthread_create线程函数二、pthread_join()函数三、互斥锁 pthread_mutex_init()函数

一、pthread_create线程函数

pthread_create是UNIX环境创建线程函数 头文件 #include<pthread.h> 函数声明 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); 返回值 第一个参数为指向线程标识符的指针。 第二个参数用来设置线程属性。 第三个参数是线程运行函数的起始地址。 最后一个参数是运行函数的参数。 另外,在编译时注意加上-lpthread参数,以调用静态链接库。

示例1 example1.c

#include <stdio.h> #include <stdlib.h> #include <pthread.h> //这里要返回void信号 void* myfunc(void* args) { printf("Hello World!\n"); return NULL; } int main() { pthread_t th; //定义变量th,表示是新的线程 pthread_create(&th, NULL, myfunc, NULL); pthread_join(th, NULL); //表示等待线程结束 return 0; }

编译:gcc example.c -lpthread -o example 执行:./example 结果: Hello World!

二、pthread_join()函数

函数声明: pthread_t th; pthread_create(&th, NULL, my_func,NULL); pthread_join(th,NULL); 创建线程之后直接调用pthread_join方法就行了。

在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到pthread_join()方法了。 即pthread_join()的作用可以这样理解:主线程等待子线程的终止。也就是在子线程调用了pthread_join()方法后面的代码,只有等到子线程结束了才能执行。

示例2 多线程 example2.c

#include <stdio.h> #include <stdlib.h> #include <pthread.h> void* myfunc(void* args) { int i; char * name = (char*) args; for(i=1; i<10; i++) { printf("%s: %d\n", name, i); } return NULL; } int main() { pthread_t th1; pthread_t th2; pthread_create(&th1, NULL, myfunc, "th1"); pthread_create(&th2, NULL, myfunc, "th2"); pthread_join(th1, NULL); pthread_join(th2, NULL); return 0; }

编译:gcc example2.c -lpthread -o example2 执行:./example2 结果: th2: 1 th2: 2 th2: 3 th2: 4 th2: 5 th2: 6 th2: 7 th2: 8 th2: 9

三、互斥锁 pthread_mutex_init()函数

linux下为了多线程同步,通常用到锁的概念。 posix下抽象了一个锁类型的结构:ptread_mutex_t。通过对该结构的操作,来判断资源是否可以访问。顾名思义,加锁(lock)后,别人就无法打开,只有当锁没有关闭(unlock)的时候才能访问资源。 即对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。 使用互斥锁(互斥)可以使线程按顺序执行。通常,互斥锁通过确保一次只有一个线程执行代码的临界段来同步多个线程。互斥锁还可以保护单线程代码。 要更改缺省的互斥锁属性,可以对属性对象进行声明和初始化。通常,互斥锁属性会设置在应用程序开头的某个位置,以便可以快速查找和轻松修改。 1.函数原型: int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);

该函数用于C函数的多线程编程中,互斥锁的初始化。

示例3 加锁

#include <stdio.h> #include <stdlib.h> #include <pthread.h> pthread_mutex_t lock; int s =0; void* myfunc(void* args) { int i = 0; pthread_mutex_lock(&lock); for(i=0; i<1000000; i++) { s++; } pthread_mutex_unlock(&lock); return NULL; } int main() { pthread_t th1; pthread_t th2; pthread_mutex_init(&lock, NULL); pthread_create(&th1, NULL, myfunc, NULL); pthread_create(&th2, NULL, myfunc, NULL); pthread_join(th1, NULL); pthread_join(th2, NULL); printf("s = %d\n", s); return 0; }

编译:gcc example3.c -lpthread -o example3 执行:./example3 结果: s = 2000000

这里加锁和在同一次执行两次for循环,好比示例4中把5000拆成两次再运算。 示例4

#include <stdio.h> #include <stdlib.h> #include <pthread.h> typedef struct { int first; int last; } MY_ARGS; int arr[5000]; int s = 0; void* myfunc(void* args) { int i; MY_ARGS* my_args = (MY_ARGS*) args; //强制转换 ,把args的void信号转换成MY_ARGS int first = my_args -> first; int last = my_args -> last; for(i=first; i<last; i++) { s = s + arr[i]; } return NULL; } int main() { //生成随机数 int i; for (i=0; i<5000; i++) { arr[i] = rand() % 50; } pthread_t th1; pthread_t th2; //设置运行的参数 MY_ARGS args1 = {0, 2500}; MY_ARGS args2 = {2500, 5000}; pthread_create(&th1, NULL, myfunc, &args1); //这里把参数传进args pthread_create(&th2, NULL, myfunc, &args2); pthread_join(th1, NULL); pthread_join(th2, NULL); printf("s = %d\n", s); return 0; }

结果: s = 122607

最新回复(0)