#include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<string.h>void *fun(void *s){ int i=10; while(i) { printf("线程打开\n"); i--; } pthread_exit(NULL);//线程退出,可以带出返回值}int main(void){ pthread_t pid; int ret= pthread_create(&pid,NULL,fun,NULL);//创建一个线程,传入参数需要依靠(void *)做强转 if(ret!=0) { strerror(ret); exit(1); } pthread_join(pid,NULL);//线程收尸可以接收返回值}
5、线程同步:此操作目的在于解决线程存在的竞争问题 sudo apt-get install manpages-posix-dev 互斥量:pthread_mutex_t mutex; pthread_mutex_init(互斥量指针,互斥量指针属性):初始化互斥量 属性:NULL为默认属性 使用宏初始化:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_destroy(互斥量指针):销毁互斥量 pthread_mutex_lock(互斥量指针):申请锁,若锁可用,获得锁并加锁,若不可用,阻塞 pthread_mutex_unlock(互斥量指针):解锁 池类算法 sched_yield():出让调度器 eg:计算质数不加互斥量 #include<stdio.h> #include<stdlib.h> #include<pthread.h> #include<string.h> #define MIN 30000000 #define MAX 30000200 #define PHMAX 3 static int num=0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void *fun(void *s) { int i=0; while(1) { int flag=1; if(num==-1) break; while(num==0); i=num;//接到数据先接受 num=0;//再将数据变为0 告诉主线程该仍数据了 for(int j=2;j<i/2;j++) { if(i%j==0) { flag=0; break; } } if(flag) printf("%d\n",i); } //结束掉线程 pthread_exit(NULL); } int main(void) { pthread_t pid[PHMAX]; int i=0; //创建三个线程 for( i=0;i<PHMAX;i++) { int ret= pthread_create(&pid[i],NULL,fun,NULL); if(ret!=0) { strerror(ret); exit(1); } } for(int j=MIN;j<MAX;j++) { while(num!=0);//子线程如果将num变为0,那么可以再给下一个数了,不然就死等 num=j; } while(num!=0); num=-1;//数据仍完 //给线程收尸 for(int m=0;m<PHMAX;m++) pthread_join(pid[m],NULL); exit(1);}
计算结果:
线程出现竞争关系并且无法自己退出
eg:添加互斥量
/************************************************************************* > File Name: ph.c > Author: > Mail: > Created Time: 2017年10月29日 星期日 22时10分49秒 ************************************************************************/#include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<string.h>#include<sched.h>#define MIN 30000000#define MAX 30000500pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;//初始化我的互斥量#define PHMAX 3static int num=0;void *fun(void *s){ int i=0; while(1) { pthread_mutex_lock(&mutex);//如果线程强到资源那么我就把门锁上 int flag=1; if(num==-1) { pthread_mutex_unlock(&mutex);//如果是-1,那么我就解锁并且跳出循环 break; } while(num==0); i=num; num=0; pthread_mutex_unlock(&mutex);//我得到数据之后就把锁释放掉让别人去抢主线程的资源 //然后做自己该干的主要事情 for(int j=2;j<i/2;j++) { if(i%j==0){ flag=0; break; } //printf("%d\n",i ); } if(flag) printf("%d\n",i); } pthread_exit(NULL);}int main(void){ pthread_t pid[PHMAX]; int i=0; pthread_mutex_init(&mutex,NULL);//初始化互斥量 for( i=0;i<PHMAX;i++) { int ret= pthread_create(&pid[i],NULL,fun,NULL); if(ret!=0) { strerror(ret); exit(1); } } for(int j=MIN;j<MAX;j++) { //printf("j:%d\n",j); // pthread_mutex_lock(&mutex); while(num!=0)//如果这里不等于0就说明我的东西没有被其他线程抢走,那我就等他们把数据抢走 { //pthread_mutex_unlock(&mutex); //sched_yield();//出让调度器 //pthread_mutex_lock(&mutex); } num=j; //pthread_mutex_unlock(&mutex); } while(num!=0);//我发的东西还没抢完,或者还没人搞事, //别人已经把最后的数据拿到了 pthread_mutex_lock(&mutex);//我就枪锁关门 num=-1;//把数据变为-1,让其他线程都拿到 pthread_mutex_unlock(&mutex);//解锁让孩儿们去强吃的pthread_mutex_destroy(&mutex);//销毁掉我的互斥量 for(int m=0;m<PHMAX;m++) pthread_join(pid[m],NULL); exit(1);}
结果输出:
条件变量:pthread_cond_t pthread_cond_init(条件变量指针,属性):初始化条件变量 属性:NULL为默认属性 使用宏初始化:pthread_cond_t cond = PTHREAD_COND_INITIALIZER; ptherad_cond_destroy(条件变量指针):销毁条件变量 pthread_cond_wait(条件变量指针,互斥量指针):解锁等待通知,被唤醒后再申请锁 pthread_cond_broadcast(条件变量指针):唤醒所有的等待线程 pthread_cond_signal(条件变量指针):唤醒任意一个等待的线程
改变通知法:
/************************************************************************* > File Name: ph_mycopy.c > Author: > Mail: > Created Time: 2017年10月30日 星期一 14时20分03秒 ************************************************************************/#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<pthread.h>#include <sys/stat.h>#include <fcntl.h>#define BUFSIZE 1024#define THREADNUM 4//定义线程数量#define FILESIZE 13331520static int num=FILESIZE/THREADNUM;static int th=0;pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;void *fun(void *s){ int sum; char buf[BUFSIZE]; int res; int file,file2; int i=0; file=open("./tmp.mp3",O_WRONLY); file2=open("./s.mp3",O_RDONLY); pthread_mutex_lock(&mutex); //使用互斥量使得偏移量不回发生竞争关系 i=th; th++; pthread_mutex_unlock(&mutex); lseek(file,num*i,SEEK_SET); lseek(file2,num*i,SEEK_SET); while(1) { res=read(file2,buf,BUFSIZE); if((sum>(FILESIZE/THREADNUM))||res==0) { printf("I:%d,sum:%d:pthread_self:%u\n",i,sum,pthread_self() ); break; } write(file,buf,res); sum+=res; } close(file); close(file2); pthread_exit(NULL);}int main(int argc,char *argv[]){ FILE * file; pthread_t tid[THREADNUM]; int i; pthread_mutex_init(&mutex,NULL);//条件变量 file=fopen("./tmp.mp3","w"); fseek(file,FILESIZE-1,SEEK_END); fwrite("\0",1,1,file); fclose(file); for(i=0;i<THREADNUM;i++) { pthread_create(&tid[i],NULL,fun,NULL);//创建线程 } for(int m=0;m<THREADNUM;m++) pthread_join(tid[m],NULL);pthread_mutex_destroy(&mutex); exit(1);
}