初探线程之线程竞争及故障

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

猜你喜欢

转载自blog.csdn.net/ZZHinclude/article/details/119647711