背景思考:
最开始操作系统是只能处理单个任务的,且内存中只能存一个程序,然后出现了批处理的系统,这样我一批任务给操作系统,我走了,明天都处理完了,然后出现了多进程或者多线程,这个的出现造就了分时任务,或许就是因为分时任务的需求出现了多线程或者多进程。
多线程或多进程带来了什么好处?
1.即使我只有一个cpu也是有好处的,因为只要内存中存在多个程序,那么如果程序一阻塞了,我就可以让程序二运行,切换到线程二即可,挂起线程一,线程一要是准备好了,给cpu发送一个中断信号然后再切换到程序一(也就是线程一)执行就行了。
2.要是多cpu的更不用说了,单cpu只能算是并发,而多cpu是真正意义上的并行,如果在单cpu上面编程其实我觉得是不会涉及到多线程编程的问题(也就是共享变量的问题),虽然共享变量,但是不会真正意义上同时操作,所以是没有任何问题的,但是这也取决于你语言成面的内存模型的可见性问题。
最近因为朋友让我帮他看一下linux c多线程的一个问题,我就答应研究一下(其实我是很喜欢linux c系统编程的,之前也研究过一段时间),所以我就顺便研究一下pthread,就是linux c下的多线程的问题,我们都知道摩尔定律已经失效了,现在cpu架构从之前的提升cpu的频率到现在向多核方向发展,既然是多核心,那么多线程肯定是必需品。
#include <stdio.h>
#include <pthread.h>
#define N 10
//互斥量 就是锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void * myThread(void *arg){
int id = *(int *)arg;
int i;
printf("current thread is :%d\n",id);
//线程操作前要加锁
pthread_mutex_lock(&mutex);
for(i=0;i<N;i++){
printf("current thread :%d print\n",id);
sleep(1);
}
//释放后要解锁
pthread_mutex_unlock(&mutex);
}
int main(){
pthread_t thread[N];
int id[N],i;
for(i=0;i<N;i++){
id[i] = i;
/*
创建线程
第一个参数:传入pthread_t 声明的线程地址
第二个参数:传入NULL即可
第三个参数:传入线程入口地址 函数指针
第四个参数:传入给线程的参数 void*类型的
*/
pthread_create(&thread[i], NULL, myThread, &id[i]);
}
//当前线程等待所有线程运行完,然后才继续运行,和java的api类似
for(i=0;i<N;i++){
pthread_join(thread[i],NULL);
}
return 0;
}
解决实际问题:
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<pthread.h>
#define P 3
#define Q 4
pthread_mutex_t mutex[10];
struct demo_parameters {
int S;
int M;
};
struct demo_srelation{
int sid;
int mid;
};
struct demo_mrelation{
//该marker是否结束
bool finish;
//如果没有结束 那么查看该字段是否是空闲的
bool free;
//该marker的线程id
int mid;
//抓取该marker的student 线程id
int sid;
};
struct demo_srelation srelation[10];
struct demo_mrelation mrelation[10];
struct demo_parameters parameters;
bool grabMarker(int sid){
int i;
int count = 0;
for(i=0;i<10;i++){
bool finish = mrelation[i].finish;
bool free = mrelation[i].free;
if(!finish&&free){
mrelation[i].sid = sid;
count++;
if(count==P){
break;
}
}
}
return true;
}
bool haveTime(){
return true;
}
void *studentT(void *argv){
int studentId = *(int *)argv;
printf("current student :%d\n",studentId);
bool ok = grabMarker(studentId);
bool havetime = haveTime();
if(ok&&havetime){
printf("ok\n");
}
}
void *markerT(void *argv){
int markerId = *(int *)argv;
int count =0;
int i;
while(1){
printf("current marker:%d is running\n",markerId);
printf("was grabbed by the student :%d\n",mrelation[markerId].sid);
count++;
if(count>=Q){
mrelation[markerId].finish = true;
break;
}
}
}
int main(int argc,char *argv[]){
if(argc<2){
printf("parameters error\n");
}
parameters.S = atoi(argv[1]);
parameters.M = atoi(argv[2]);
int S = parameters.S;
int M = parameters.M;
int i;
if(S>100 || M>100){
puts("Maximum 100 markers and 100 students allowd\n");
exit(1);
}
printf("SN : %d ,MN: %d \n",S,M);
for(i=0;i<10;i++){
pthread_mutex_init ( &(mutex[i]), NULL);
}
pthread_t student[S];
pthread_t marker[M];
int studentId[S];
int markerId[M];
for(i=0;i<S;i++){
studentId[i] = i;
pthread_create(&student[i],NULL,studentT,&studentId[i]);
}
for(i=0;i<M;i++){
markerId[i] = i;
pthread_create(&marker[i],NULL,markerT,&markerId[i]);
}
for (i = 0; i<S; i++) {
pthread_join(student[i], NULL);
}
for (i = 0; i<M; i++) {
pthread_join(marker[i], NULL);
}
return 0;
}