1.一个demo
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define LEFT 30000000
#define RIGHT 30000200
#define SIZE (RIGHT-LEFT+1)
void * Fun(void *p)
{
int nNum = * (int *)p;
int Flag = 1;
int j;
for(j = 2; j < nNum/2; j++)
{
if(0 == nNum % j)
{
Flag = 0;
}
}
if(Flag)
{
printf("%d is a prime\n", nNum);
}
pthread_exit(NULL);
}
int main()
{
pthread_t tid[SIZE];
int i,err;
for(i = LEFT ; i <= RIGHT; i++)
{
err = pthread_create(tid+(i-LEFT), NULL, Fun, &i);
if(err)
{
fprintf(stderr, "create()%s ", strerror(err));
exit(1);
}
}
for(i = LEFT; i <= RIGHT; i++)
{
pthread_join(tid[i-LEFT], NULL);
}
return 0;
}
我先创建了201个线程,然后每一个线程计算一个数字,最后在join
可是结果一直不对
最离谱的结果是输出了十几个3000000是一个质数,原因是因为产生了竞争
err = pthread_create(tid+(i-LEFT), NULL, Fun, &i);
int nNum = * (int *)p;
一直在创建线程,可是当前面的线程没有执行赋值语句,i的值就被改变了
2.改进
①最丑陋的一个做法
err = pthread_create(tid+(i-LEFT), NULL, Fun, (void *)i);
int nNum = (int )p;
直接不传递地址了,强转
②给201个不同地址的空间,这也不会冲突
③还需改进 后续学习。。。。。
3.
每个线程的栈是独立的,你每个栈的大小越小,则该进程可以创建的线程越多,ulimit默认一个线程的大小是10M,32位地址空间,一个进程的虚拟大小是4G,内核态占据1G
4.一个demo
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define THRNUM 20
#define FILENAME "log"
#define LINESIZE 1024
void * Fun(void *p)
{
FILE *fp = fopen(FILENAME,"r+");
char Buf[LINESIZE];
if(NULL == fp)
{
perror("fopen()");
exit(1);
}
fgets( Buf, LINESIZE, fp);
fseek(fp, 0, SEEK_SET);
fprintf(fp, "%d\n", atoi(Buf)+1);
//fflush(NULL);
fclose(fp);
pthread_exit(NULL);
}
int main()
{
pthread_t tid[THRNUM];
int i,err;
for(i = 0 ; i <= THRNUM; i++)
{
err = pthread_create(tid+i, NULL, Fun, NULL);
if(err)
{
fprintf(stderr, "create()%s ", strerror(err));
exit(1);
}
}
for(i = 0; i <= THRNUM; i++)
{
pthread_join(tid[i], NULL);
}
return 0;
}
创建20个线程,读取同一个文件,取出来数字,然后加1写回,log起初是1
我们执行完之后,应该是21
5.解决方式 互斥量
如果我们对文件 只进行打开和读取的话,那没有问题,但是我们进行了写入,所以我们必须得把写操作这一段代码加上锁,每次只允许一个线程对这个文件进行写,别的就在那里阻塞
限制了某段代码的运行,而非某个变量
NAME
pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock
- lock and unlock a mutex
SYNOPSIS
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
NAME
pthread_mutex_destroy, pthread_mutex_init - destroy and
initialize a mutex
SYNOPSIS
#include <pthread.h>
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
#define THRNUM 20
#define FILENAME "log"
#define LINESIZE 1024
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
void * Fun(void *p)
{
FILE *fp = fopen(FILENAME,"r+");
char Buf[LINESIZE];
if(NULL == fp)
{
perror("fopen()");
exit(1);
}
pthread_mutex_lock(&mut);
fgets( Buf, LINESIZE, fp);
fseek(fp, 0, SEEK_SET);
fprintf(fp, "%d\n", atoi(Buf)+1);
fclose(fp);
pthread_mutex_unlock(&mut);
pthread_exit(NULL);
}
int main()
{
pthread_t tid[THRNUM];
int i,err;
for(i = 0 ; i <= THRNUM; i++)
{
err = pthread_create(tid+i, NULL, Fun, NULL);
if(err)
{
fprintf(stderr, "create()%s ", strerror(err));
exit(1);
}
}
for(i = 0; i <= THRNUM; i++)
{
pthread_join(tid[i], NULL);
}
pthread_mutex_destroy(&mut);
return 0;
}