线程概述
线程基本编程
函数说明
pthread_create(): | 创建线程,成功返回0 |
pthread_exit(): | 主动退出线程,成功返回0 |
pthread_join(): | 挂起线程等待结束,成功返回0 |
pthread_cancel | 在别的线程中终止另一个线程的执行,成功返回0 |
示例代码:创建三个线程,每个线程重用同一个执行,每个线程五次循环,每次循环随机等待1-10s。
/* thread.c */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define THREAD_NUMBER 3 /*宏定义线程数量*/
#define REPEAT_NUMBER 5 /*宏定义每个线程的任务数量*/
#define DELAY_TIME_LEVELS 10.0/*小任务之间的最大时间间隔*/
/*定义线程处理过程的函数*/
void * thrd_func(void *arg)
{
int thrd_num = (int)arg;
int delay_time = 0;
int count = 0;
printf("Thread %d is starting\n", thrd_num);
/*循环每个线程调用这个线程处理函数的时候要进行五次任务,所以循环五次*/
for (count = 0; count < REPEAT_NUMBER; count++)
{
delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
sleep(delay_time);
/*线程几:工作 几 次 等待 几 秒*/
printf("\tThread %d: job %d delay = %d\n", thrd_num, count, delay_time);
}
printf("Thread %d finished\n", thrd_num);/*五次任务做完要输出线程几完成了*/
pthread_exit(NULL);
}
/*主函数*/
int main(void)
{
/*结构体解释:
typedef unsigned long int pthread_t;
用途:pthread_t用于声明线程ID。
sizeof(pthread_t) =4;*/
/*先赋值工作数*/
pthread_t thread[THREAD_NUMBER];
int no = 0, res;
void * thrd_ret;
srand(time(NULL));
/*
time(NULL);就是返回从1970年元旦午夜0点到现在的秒数。 srand(time(NULL)); 是以当前时间为种子,产生随意数。
srand和rand()配合使用产生伪随机数序列。
rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。
如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。
srand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,
从而实现真正意义上的“随机”。通常可以利用系统时间来改变系统的种子值,
即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列
*/
/*循环创建三个线程*/
for (no = 0; no < THREAD_NUMBER; no++)
{
res = pthread_create(&thread[no], NULL, thrd_func, (void*)no);
/*
&thread[no]:线程标识符,表示线程的标号;
NULL:线程属性,通常取NULL;
thrd_func:线程处理函数;
(void*)no:传递给线程处理函数的参数;
函数成功执行返回0,出错返回错误码;
pthread_create()函数作用,创建一个线程,并指定线程处理函数thrd_func,从而执行该函数规定的动作;
*/
if (res != 0)
{
printf("Create thread %d failed\n", no);/*pthread_create失败返回0*/
exit(res);
}
}
printf("Create threads success,Waiting for threads to running..\n");/*成功输出这句*/
/*循环挂起线程*/
for (no = 0; no < THREAD_NUMBER; no++)
{
res = pthread_join(thread[no], &thrd_ret); //&thrd_ret:用户定义的指针,用来存储被等待线程结束时返回值;
/*pthread_join使一个线程等待另一个线程结束。
代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。
加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。
该函数作用:当thread[no]尚未运行结束时,调用pthread_join()的主进程阻塞,直到thread[no]线程退出,该线程所占据的资源才被释放,主进程才能结束;
主进程等待线程运行结束后,pthread_join函数返回0,该线程资源释放;如果出错返回错误码;
*/
if (!res)
{
printf("Thread %d joined\n", no);/*该语句打印出来代表thread[no]已经结束运行,释放其占据的资源*/
}
else
{
printf("Thread %d join failed\n", no);
}
}
return 0;
}
线程之间的同步互斥
信号量适用于同时可用的资源是多个
互斥锁适用于同时可用的资源唯一
互斥锁线程控制
互斥锁初始化 | pthread_muttex_init |
互斥锁上锁 | pthread_muttex_lock |
互斥锁判断上锁 | pthread_muttex_trylock() |
互斥锁解锁 | pthread_muttex_unlock |
消除互斥锁 | pthread_muttex_destroy |
示例代码(是在上一个示例基础上增加了互斥锁的功能):
/* thread_mutex.c */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define THREAD_NUMBER 3 /*有三个线程*/
#define REPEAT_NUMBER 3 /*每个线程三个任务*/
#define DELAY_TIME_LEVELS 10.0 /*每个线程任务随机等待1-10s*/
pthread_mutex_t mutex;
/**/
void * thrd_func(void *arg)
{
int thrd_num = (int)arg;
int delay_time = 0, count = 0;
int res;
res = pthread_mutex_lock(&mutex); /*上互斥锁,成功返回0,非0值代表失败,并返回出错信息;*/
if (res)
{
/*上锁失败*/
printf("Thread %d lock failed\n", thrd_num);
pthread_exit(NULL);
}
/*上锁成功输出一句线程开始*/
printf("Thread %d is starting\n", thrd_num);
/*三次任务*/
for (count = 0; count < REPEAT_NUMBER; count++)
{
delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
sleep(delay_time);
printf("\tThread %d: job %d delay = %d\n", thrd_num, count, delay_time);
}
/*线程完成*/
printf("Thread %d finished\n", thrd_num);
/*主动停止线程*/
pthread_exit(NULL);
}
int main(void)
{
/*一些定义*/
pthread_t thread[THREAD_NUMBER];
int no = 0, res;
void * thrd_ret;
srand(time(NULL));
/*互斥锁初始化*/
pthread_mutex_init(&mutex, NULL);
/*参数解释:
&mutex创建互斥锁,都这么写
NULL表示创建的是快速互斥锁,调用线程会阻塞直至拥有互斥锁的线程解锁为止,知道有这么回事就好
*/
/*循环创建三个线程*/
for (no = 0; no < THREAD_NUMBER; no++)
{
/*线程号,默认NULL,线程处理函数,传递参数*/
res = pthread_create(&thread[no], NULL, thrd_func, (void*)no);
if (res != 0)
{
printf("Create thread %d failed\n", no);/*报错*/
exit(res);
}
}
printf("Create threads success\n Waiting for threads to finish...\n");/*创建成功,等待线程创建完毕*/
/*做三次任务,每个线程挂起,防止退出太快*/
for (no = 0; no < THREAD_NUMBER; no++)
{
res = pthread_join(thread[no], &thrd_ret);
if (!res)
{
printf("Thread %d joined\n", no);
}
else
{
printf("Thread %d join failed\n", no);
}
pthread_mutex_unlock(&mutex);/*解开互斥锁*/
}
pthread_mutex_destroy(&mutex); /*消除(删除)互斥锁*/
return 0;
}
信号量线程控制
互斥锁是一种特殊的信号量,互斥锁初始值为1,信号量初始值为0