互斥
简单地理解就是,一个线程进入工作区后,如果有其他线程想要进入工作区,它就会进入等待状态,要等待工作区内的线程结束后才可以进入。
基本函数
(1) pthread_mutex_init函数
原型:int pthread_mutex_init ( pthread_mutex_t *mutex, const pthread_mutexattr_t* attr);
描述:设置互斥量的属性
参数:第一个参数:预先声明的pthread_mutex_t对象指针
第二个参数:互斥锁属性,NULL表示使用默认属性
返回值:成功时返回0, 失败时返回一个错误代码
(2) pthread_mutex_lock函数
原型:int pthread_mutex_lock ( pthread_mutex_t *mutex );
描述:pthread_mutex_lock返回时,互斥锁被锁定,如果这个互斥锁被一个线程锁定和拥有,那么另一个线程要调用这 个函数会进入堵塞状态(即等待状态),直到互斥锁被释放为止。
返回值:成功时返回0, 失败时返回一个错误代码
(3) pthread_mutex_unlock函数
原型:int pthread_mutex_unlock ( pthread_mutex_t *mutex );
描述:释放互斥锁
返回值:成功时返回0, 失败时返回一个错误代码
(4) pthread_mutex_destroy函数
原型:int pthread_mutex_destroy ( pthread_mutex_t *mutex );
描述:删除互斥锁
返回值:成功时返回0, 失败时返回一个错误代码
实例
lock.c文件
描述:这个程序主要可以概括为主线程负责接受输入的字符串,而子线程则负责统计并输出字符数。
#include
#include
#include
#include
#include
void *thread_function(void *arg);
pthread_mutex_t work_mutex;
#define WORK_SIZE 1024
char work_area[WORK_SIZE];
int time_to_exit = 0;
int main() {
int res;
pthread_t a_thread;
void *thread_result;
/*初始化互斥量*/
res = pthread_mutex_init(&work_mutex, NULL);
if (res != 0) {
perror("互斥量初始化失败!");
exit(EXIT_FAILURE);
}
/*启动新线程*/
res = pthread_create(&a_thread, NULL, thread_function, NULL);
if (res != 0) {
perror("线程创建失败");
exit(EXIT_FAILURE);
}
pthread_mutex_lock(&work_mutex);
printf("请输入一些文本内容. 输入“end”结束\n");
while(!time_to_exit) {
fgets(work_area, WORK_SIZE, stdin);
pthread_mutex_unlock(&work_mutex);
while(1) {
pthread_mutex_lock(&work_mutex);
/*统计字符工作未完成*/
if (work_area[0] != '\0') {
pthread_mutex_unlock(&work_mutex);
sleep(1);
}
else {
/*统计字符工作完成,跳出内层循环,重新读取输入*/
break;
}
}
}
pthread_mutex_unlock(&work_mutex);
printf("\n等待线程结束...\n");
res = pthread_join(a_thread, &thread_result);
if (res != 0) {
perror("Thread join failed");
exit(EXIT_FAILURE);
}
printf("Thread joined\n");
pthread_mutex_destroy(&work_mutex);
exit(EXIT_SUCCESS);
}
/*主线程首先锁定工作区,在获取输入的字符后,释放工作区,让其他线程对字符个数进行统计。work_area[0[为空字符时表示统计结束。通过周期性地对互斥量进行加锁,检查是否已经统计完。*/
/*在线程中要执行的代码*/
void *thread_function(void *arg) {
sleep(1);
pthread_mutex_lock(&work_mutex);
while(strncmp("end", work_area, 3) != 0) {
printf("你输入了 %d 个字符\n", strlen(work_area) -1);
work_area[0] = '\0';
pthread_mutex_unlock(&work_mutex);
sleep(1);
pthread_mutex_lock(&work_mutex);
while (work_area[0] == '\0' ) {
pthread_mutex_unlock(&work_mutex);
sleep(1);
pthread_mutex_lock(&work_mutex);
}
}
time_to_exit = 1;
work_area[0] = '\0';
pthread_mutex_unlock(&work_mutex);
pthread_exit(0);
}
/*在新线程一上来先试图对互斥量进行加锁。如果它已经被锁上,新线程就会进入堵塞状态知道互斥锁释放为止,一旦可以进入工作区,就先检查是否有退出请求(end)如果有,就设置time_to_exit变量和work_area,然后退出程序。
如果没有退出,那么就对字符个数进行统计。把work_area[0]设置为空,表示统计工作完成。接下来就释放互斥锁,等待主线程的运行,周期性地给互斥量加锁,如果加锁成功,就检查主线程是否又给我们新的字符串统计。如果没有,就释放互斥锁继续等待,*/
编译执行:gcc -D_REENTRANT fork.c -o fork -lpthread
运行结果如下:
���考文献:Linux程序设计