目录
线程同步
线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据一致性,不能调用该功能。
协调同步,对公共区域数据按序访问。防止数据混乱,产生与时间有关的错误。
锁的使用
建议锁。对公共数据进行保护。所有线程应该在访问公共数据前先拿锁再访问。但锁本身不具备强制性。
注意事项
尽量保证锁的粒度,越小越好。访问共享数据前,加锁。访问结束,立即解锁。
互斥锁本质是结构体。
pthread_mutex_init
初始化一个互斥锁(互斥量),初值可看作1。
man pthread_mutex_init
注意
对于这个没有手册页条目问题,直接安装manpages-posix-dev即可。
sudo apt-get install manpages-posix-dev
参数mutex
传出参数,调用时传&mutex。
restrict关键字:只用于限制指针,告诉编译器,所有修改该指针指向内存中内容的操作,只能通过本指针完成。不能通过除本指针以外的其他变量或指针修改。
参数attr
互斥量属性,是一个传入参数,通常传NULL,选用默认属性(线程间共享)。
返回值
成功:0
失败:错误号
动态初始化
pthread_mutex_t mutex;
pthread_mutex_init(&mutex,NULL); //动态初始化
静态初始化
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; //静态初始化
pthread_mutex_destroy
销毁一个互斥锁。
man pthread_mutex_destroy
参数mutex
传出参数,调用时传&mutex。
返回值
成功:0
失败:错误号
pthread_mutex_lock
加锁。可理解为将mutex--(或 -1),操作后mutex的值为 0。
man pthread_mutex_lock
参数mutex
传出参数,调用时传&mutex。
返回值
成功:0
失败:错误号
pthread_mutex_unlock
解锁。可理解为将mutex++(或+1),操作后mutex的值为1。
man pthread_mutex_unlock
参数mutex
传出参数,调用时传&mutex。
返回值
成功:0
失败:错误号
pthread_mutex_trylock
尝试加锁。
man pthread_mutex_trylock
参数mutex
传出参数,调用时传&mutex。
返回值
成功:0
失败:错误号,同时设置错误EBUSY。
测试代码1
借助互斥锁管理共享数据实现同步。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>
pthread_mutex_t Suo; //锁
int flag;
void *HuiDiao_HanShu(void *arg)
{
srand(time(NULL));
while (1)
{
flag = pthread_mutex_lock(&Suo); //加锁
if (flag != 0)
{
printf("加锁错误:%s\n", strerror(flag));
exit(1);
}
printf("你好,");
sleep(rand() % 3);
printf("世界。\n");
flag = pthread_mutex_unlock(&Suo); //解锁
if (flag != 0)
{
printf("解锁错误:%s\n", strerror(flag));
exit(1);
}
sleep(rand() % 3);
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t ZiXianCheng_ID; //子线程ID
void *num = NULL;
srand(time(NULL));
flag = pthread_mutex_init(&Suo, NULL); //初始化锁
if (flag != 0)
{
printf("初始化锁错误:%s\n", strerror(flag));
exit(1);
}
flag = pthread_create(&ZiXianCheng_ID, NULL, HuiDiao_HanShu, NULL); //创建子线程
if (flag != 0)
{
printf("创建子线程错误:%s\n", strerror(flag));
exit(1);
}
while (1)
{
flag = pthread_mutex_lock(&Suo); //加锁
if (flag != 0)
{
printf("加锁错误:%s\n", strerror(flag));
exit(1);
}
printf("NiHao,");
sleep(rand() % 3);
printf("ShiJie。\n");
flag = pthread_mutex_unlock(&Suo); //解锁
if (flag != 0)
{
printf("解锁错误:%s\n", strerror(flag));
exit(1);
}
sleep(rand() % 3);
}
printf("开始回收子线程!\n");
flag = pthread_join(ZiXianCheng_ID, NULL);
if (flag != 0)
{
printf("回收子线程错误:%s\n", strerror(flag));
exit(1);
}
printf("回收子线程完成!\n");
flag = pthread_mutex_destroy(&Suo); //销毁锁
if (flag != 0)
{
printf("销毁锁错误:%s\n", strerror(flag));
exit(1);
}
pthread_exit(NULL);
return 0;
}