Linux|Linux:线程同步
1.线程:进程内部的一条执行路径(序列),调度的基本单位
进程: 一个正在运行的程序,动态分配基本单位
线程可以是程序可靠性降低,用线程可以利用多个处理器的资源
pv操作是原子操作
2. 创建信号量
#include
#include
#include
#include
#include【Linux|Linux:线程同步】void* fun(void* arg)//创建信号量
{char arr[]={
"1 2 3 4 5 6 7"};
char*s=strtok(arr,"");
//分隔信号量
while(s!=NULL)
{printf("thread s=%s\n",s);
sleep(1);
s=strtok(NULL,"");
}
}
int main()
{pthread_t id;
pthread_create(&id,NULL,fun,NULL);
char str[]={
"a b c d e f g"};
char *p=strtok(str,"");
while(p!=NULL)
{printf("main p=%s\n",p);
sleep(1);
p=strtok(NULL,"");
}
pthread_join(id,NULL);
//线程结束
exit(0);
}
运行结果:
文章图片
3.(1)strtok函数不能在多线程中使用,因为它非线程安全函数,只能在单线程使用
(2)线程安全:多线程程序无论调度顺序如何,都能得到正确的一致的效果
(3)线程安全函数:
strtok 非线程安全函数
strtok_r 线程安全函数
(4)解决线程安全问题方法:同步,使用线程安全的函数
(5)非线程安全函数由什么原因导致?
在函数内部使用全局变量或静态变量
三个同时创建线程:
#include
#include
#include
#include
#include#includesem_t sem1,sem2,sem3;
//三个线程打印数字a,b,c
void* fun1(void* arg)
{int i=0;
for(;
i<5;
i++)
{sem_wait(&sem1);
//p操作
printf("A");
fflush(stdout);
sem_post(&sem2);
//v操作
sleep(1);
}
}
void* fun2(void* arg)
{int i=0;
for(;
i<5;
i++)
{sem_wait(&sem2);
//p操作
printf("B");
fflush(stdout);
sem_post(&sem3);
//v操作
sleep(1);
}
}
void* fun3(void* arg)
{int i=0;
for(;
i<5;
i++)
{sem_wait(&sem3);
//p操作
printf("C");
fflush(stdout);
sem_post(&sem1);
//v操作
sleep(1);
}
}
int main()
{//三个信号量初始化
sem_init(&sem1,0,1);
sem_init(&sem2,0,0);
sem_init(&sem3,0,0);
pthread_t id1,id2,id3;
pthread_create(&id1,NULL,fun1,NULL);
pthread_create(&id2,NULL,fun2,NULL);
pthread_create(&id3,NULL,fun3,NULL);
//等待三个进程结束
pthread_join(id1,NULL);
pthread_join(id2,NULL);
pthread_join(id3,NULL);
//销毁
sem_destroy(&sem1);
sem_destroy(&sem2);
sem_destroy(&sem3);
exit(0);
}
运行结果:
文章图片
创建线程:
#include
#include
#include
#include
#include#includevoid* fun(void* arg)
{for(int i=0;
i<5;
i++)
{printf("main run\n");
sleep(1);
}
}
int main()
{pthread_t id;
pthread_create(&id,NULL,fun,NULL);
for(int i=0;
i<5;
i++)
{printf("main run\n");
sleep(1);
}
}
运行结果:
文章图片
执行5次后结束
加入fork后:
#include
#include
#include
#include
#include#includevoid* fun(void* arg)
{for(int i=0;
i<5;
i++)
{printf("main run pid=%d\n",getpid());
sleep(1);
}
}
int main()
{pthread_t id;
pthread_create(&id,NULL,fun,NULL);
fork();
for(int i=0;
i<5;
i++)
{printf("main run pid=%d\n",getpid());
sleep(1);
}
}
运行结果:
文章图片
子进程打印的数字只与fork位置有关
推荐阅读
- Linux下面如何查看tomcat已经使用多少线程
- Beego打包部署到Linux
- 多线程NSOperation
- Spectrum|Spectrum 区块偶尔停止同步问题排查与解决笔记
- Linux|109 个实用 shell 脚本
- linux定时任务contab
- 芯灵思SinlinxA33开发板Linux内核定时器编程
- MYSQL主从同步的实现
- day16-Linux|day16-Linux 软件管理
- spring|spring boot中设置异步请求默认使用的线程池