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); }

运行结果:
Linux|Linux:线程同步
文章图片

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); }

运行结果:
Linux|Linux:线程同步
文章图片

创建线程:
#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); } }

运行结果:
Linux|Linux:线程同步
文章图片

执行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); } }

运行结果:
Linux|Linux:线程同步
文章图片
子进程打印的数字只与fork位置有关

    推荐阅读