POSIX线程中互斥量的基本用法举例

#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 1024
char work_area[WORK_SIZE];
int time_to_exit = 0;

int main()
{
    int res;
    pthread_t a_thread;
    void *thread_result;
    res = pthread_mutex_init( &work_mutex, NULL );
    if( 0 != res ) {
        perror( "Mutex initialization failed");
        exit( EXIT_FAILURE );
    }

    res = pthread_create( &a_thread, NULL, thread_function, NULL );
    if( 0 != res ) {
        perror( "Thread creation failed");
        exit( EXIT_FAILURE );
    }

    pthread_mutex_lock( &work_mutex );
    printf("Input some text. Enter 'end' to finish\n");
    while( 0 == time_to_exit ) {
        fgets( work_area, WORK_SIZE, stdin );
        pthread_mutex_unlock( &work_mutex );
        while(1) {
            pthread_mutex_lock( &work_mutex );
            if( '\0' != work_area[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( a_thread, &thread_result );
    if( 0 != res ) {
        perror( "Thread join failed" );
        exit( EXIT_FAILURE );
    }

    printf("Thread joined\n");
    pthread_mutex_destroy( &work_mutex );
    exit( EXIT_SUCCESS );
}

void *thread_function( void *arg )
{
    sleep(1);
    pthread_mutex_lock( &work_mutex );
    while( 0 != strncmp( "end", work_area, 3 ) ) {
        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 );
        while( '\0' == work_area[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( 0 );
}


新线程首先试图对互斥量加锁。如果它已经被锁住,这个调用将被阻塞直到它被释放为止。一旦获得访问权,先检查是否有申请推出程序的请求。如果有,就设置 time_to_exit 变量,再把工作去的第一个字符设置为 \0 ,然后退出。

如果不想退出,就统计字符个数,然后把 work_area 数组中的第一个字符设置为null。我们用将第一个字符设置为 null 的方法通知读取输入的线程,我们已经完成了字符统计。然后解锁互斥量并等待主线程继续执行。我们将周期性地尝试给互斥量加锁,如果加锁成功,就检查是否主线程又有字符送来要处理。如果还没有,就解锁互斥量继续等待;如果有,就统计字符个数并再次进入循环。

也就是说除了第一次输入之外,其他的输入要统计的字符的时候,新线程一直同时在对互斥量加锁解锁,来判断你有没有输入完成。

主线程的代码和新线程中类似,首先给工作区加锁,读入文本到它里面,然后解锁以允许其他线程访问它并统计字符数目。周期性地对互斥量再加锁,检查字符数目是否已经统计完成。如果还需要等待,就释放互斥量。

这种通过论寻来获得结果的方法并不是好的变成方式。在实际的变成中,我们应该尽可能用信号量来避免出现这种情况。


代码运行结果:

技术分享

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。