Linux多线程练习2

来源:互联网 发布:耳机推荐 知乎 编辑:程序博客网 时间:2024/05/22 19:56

Linux多线程练习2

#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<string.h>#include<pthread.h>#include<semaphore.h>void *thread_function(void *arg);sem_t sem_bin;#define WORK_SIZE 1024char work_area[WORK_SIZE];int main(){    int res;    pthread_t thread;    void *thread_result;    res=sem_init(&sem_bin,0,0);    if(res!=0)    {        perror("semphore failed\n");        exit(0);    }    res=pthread_create(&thread,NULL,thread_function,NULL);    if(res!=0)    {        perror("pthread create failed\n");        exit(0);    }    printf("input some text. enter 'end' to finishi\n");    while((strncmp("end",work_area,3))!=0)    {        fgets(work_area,WORK_SIZE,stdin);        sem_post(&sem_bin);    }    printf("\nwaiting for thread to finish\n");    res=pthread_join(thread,&thread_result);    if(res!=0)    {        perror("thread joined failed\n");        exit(EXIT_FAILURE);    }    printf("thread exit returned %s\n",(char *)thread_result);    sem_destroy(&sem_bin);    exit(EXIT_SUCCESS);}void *thread_function(void *arg){    sem_wait(&sem_bin);    while(strncmp("end",work_area,3)!=0)    {        printf("you input %d characters \n",strlen(work_area)-1);        sem_wait(&sem_bin);    }    pthread_exit("thread exit nomaly!");            }

初始化信号量时,我们把它的值设置为0。这样,在线程函数启动时,sem_wait函数调用就会阻塞并等待信号量变为非零值。

在主线程中,我们等待直到有文本输入,然后调用sem_post增加信号量的值,这将立刻令另一个线程从sem_wait的等待中返回并开始执行。在统计完字符个数之后,它再次调用sem_wait并再次被阻塞,直到主线程再次调用sem_post增加信号量的值为止。

#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<string.h>#include<pthread.h>#include<semaphore.h>void *thread_function(void *arg);pthread_mutex_t work_mutex;#define WORK_SIZE 1024char work_area[WORK_SIZE];int time_to_exit=0;int main(){    int res;    pthread_t thread;    void *thread_result;    res=pthread_mutex_init(&work_mutex,NULL);    if(res!=0)    {        perror("semphore failed\n");        exit(EXIT_FAILURE);    }    res=pthread_create(&thread,NULL,thread_function,NULL);    if(res!=0)    {        perror("pthread create failed\n");        exit(EXIT_FAILURE);    }    pthread_mutex_lock(&work_mutex);    printf("input some text. enter 'end' to finishi\n");    while(!time_to_exit)    {        fgets(work_area,WORK_SIZE,stdin);        pthread_mutex_unlock(&work_mutex);        while(1)        {            pthread_mutex_lock(&work_mutex);            if(work_area[0]!='\0')            {                pthread_mutex_unlock(&work_mutex);                sleep(1);            }            else                    break;        }    }    pthread_mutex_unlock(&work_mutex);    printf("\nwaiting for thread to finish\n");    res=pthread_join(thread,&thread_result);    if(res!=0)    {        perror("thread joined failed\n");        exit(EXIT_FAILURE);    }    printf("thread exit returned %s\n",(char *)thread_result);    pthread_mutex_destroy(&work_mutex);    exit(EXIT_SUCCESS);}void *thread_function(void *arg){    sleep(1);    pthread_mutex_lock(&work_mutex);    while(strncmp("end",work_area,3)!=0)    {        printf("you input %d characters \n",strlen(work_area)-1);        work_area[0]='\0';        pthread_mutex_unlock(&work_mutex);        sleep(1);        pthread_mutex_lock(&work_mutex);    }    time_to_exit=1;    work_area[0]='\0';    pthread_mutex_unlock(&work_mutex);        pthread_exit("thread exit nomaly!");            }
这段代码的完成的功能和上例基本相同,因此不再过多解析。值得提出的是,这段代码中通过轮询的方法获得结果通常并不是好的编程方式,在实际的编程中,我们应该尽可能用信号量来避免出现这种情况。这里的代码只是用作示例的目的。

#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<pthread.h>#define NUM_THREADS 6//定义线程个数void *thread_function(void *arg);int main(){    int res;    pthread_t thread[NUM_THREADS];    int lots_of_threads;    for(lots_of_threads=0;lots_of_threads<NUM_THREADS;lots_of_threads++)    {        res=pthread_create(&thread[lots_of_threads],NULL,thread_function,(void *)&lots_of_threads);        if(res!=0)        {            perror("create thread failed\n");            exit(EXIT_FAILURE);        }        sleep(1);    }    printf("waiting for threads to finishi\n");    for(lots_of_threads=NUM_THREADS-1;lots_of_threads>=0;lots_of_threads--)    {        res=pthread_join(thread[lots_of_threads],NULL);        if(res==0)        {            printf("Picked u a thread\n");        }        else        {            perror("pthread joined failed\n");        }    }    printf("ALL done\n");    exit(EXIT_SUCCESS);}void *thread_function(void *arg){    int my_number=*(int *)arg;    int rand_num;    printf("thread_function is .Argument was %d\n",my_number);    sleep(2);    printf("After sleep(2) Agument is %d\n",my_number);    rand_num=1+(int)(9.0*rand()/(RAND_MAX+1.0));    sleep(rand_num);    printf("Bye from %d\n",my_number);    pthread_exit(NULL);}
这个程序中,我们创建了一个线程ID的数组,然后循环创建多个线程,创建出的线程等待一段随机时间后退出运行。在主线程中我们等待合并这些子线程,但并不是以创建它们的顺序来等待的。

我们看到在主线程中循环创建子线程的时候,有一个sleep(1),当我们把这条语句去掉以后会是什么结果呢?结果变得很是奇怪?

我们分析一下以下结果:


我们看到出现个数字6,我怎么也想不明白怎么会出现个数字6呢?

我的理解是这样的,首先这些线程跟主线程以及它们之间相互都是并发交替执行的,所以当把sleep(1)去掉以后,由于CPU执行很快,当主线程当好执行for(lots_of_threads=NUM_THREADS-1;lots_of_threads>=0;lots_of_threads--)这条语句的时候,此时把lots_of_threads赋值为了5,但是此时第五个线程刚好要执行,把当前的lots_of_threads++后调用线程创建函数把这个值传了过去就出现了上面的结果。不过这仅仅是我自己个人的推理,也许不准确,再好好研究研究吧,对于多线程编程来说,时间上的控制是最难掌握的。