pthread_mutex_init | PTHREAD_MUTEX_INITIALIZER

创建并初始化互斥锁

头文件:
    #include <pthread.h>
原型:
    int pthread_mutex_init(pthread_mutex_t *mutex,  const pthread_mutexattr_t *mutexattr);
参数:
    pthread_mutex_t *mutex:传址,创建一个互斥量;
    pthread_mutexattr_t *mutexattr:互斥锁的属性,填NULL;
返回值:
    成功,返回0;
    失败,返回非0,设置errno;
例程:
    //用宏的方式初始化
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    //用函数的方式初始化
    static pthread_mutex_t mutex;
    if(pthread_mutex_init(&mutex, NULL) != 0)
    {
        perror("pthread_mutex_init");
        return -1;
    }

pthread_mutex_lock

上锁

头文件:
    #include <pthread.h>
原型:
    int pthread_mutex_lock(pthread_mutex_t *mutex);
参数:
    pthread_mutex_t *mutex:需要上锁的互斥量的地址;
返回值:
    成功,返回0;
    失败,返回非0,设置errno;
例程:
    pthread_mutex_lock(&mutex);

pthread_mutex_unlock

解锁

头文件:
    #include <pthread.h>
原型:
    int pthread_mutex_unlock(pthread_mutex_t *mutex);
参数:
    pthread_mutex_t *mutex:需要解锁的互斥量的地址;
返回值:
    成功,返回0;
    失败,返回非0,设置errno;
例程:
    pthread_mutex_unlock(&mutex);

pthread_mutex_destroy

销毁互斥锁

头文件:
    #include <pthread.h>
原型:
    int pthread_mutex_destroy(pthread_mutex_t *mutex);
参数:
    pthread_mutex_t *mutex:需要销毁的互斥量的地址;
返回值:
    成功,返回0;
    失败,返回非0,设置errno;
例程:
    pthread_mutex_destroy(&mutex);

应用例程

用两个线程拷贝一张图片,A线程拷贝前半部分,B线程拷贝后半部分

不能使用sleep函数

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
typedef struct
{
    int fd_r;
    int fd_w;
    int size;
}__msg;
//互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//拷贝前半部分
void* handler1(void* arg)
{
    __msg msg = *(__msg*)arg;
    /********临界区********/
    pthread_mutex_lock(&mutex);
    lseek(msg.fd_r, 0, SEEK_SET);
    lseek(msg.fd_w, 0, SEEK_SET);
    int i = 0;
    char c = 0;
    int res = 0;
    for(i=0; i<msg.size/2; i++)
    {
        res = read(msg.fd_r, &c, 1);
        if(res < 0)
        {
            perror("read");
            pthread_mutex_unlock(&mutex);
            pthread_exit(NULL);
        }
        if(write(msg.fd_w, &c, 1) < 0)
        {
            perror("write");
            pthread_mutex_unlock(&mutex);
            pthread_exit(NULL);
        }
    }
    printf("前半部分拷贝完毕\n");
    pthread_mutex_unlock(&mutex);
    /********临界区********/
    pthread_exit(NULL);
}
//拷贝后半部分
void* handler2(void* arg)
{
    __msg msg = *(__msg*)arg;
    /********临界区********/
    pthread_mutex_lock(&mutex);
    lseek(msg.fd_r, msg.size/2, SEEK_SET);
    lseek(msg.fd_w, msg.size/2, SEEK_SET);
    int i = 0;
    char c = 0;
    int res = 0;
    while(1)
    {
        res = read(msg.fd_r, &c, 1);
        if(res < 0)
        {
            perror("read");
            break;
        }
        else if(0 == res)
        {
            break;
        }
        if(write(msg.fd_w, &c, 1) < 0)
        {
            perror("write");
            pthread_mutex_unlock(&mutex);
            pthread_exit(NULL);
        }
    }
    printf("后半部分拷贝完毕\n");
    pthread_mutex_unlock(&mutex);
    /********临界区********/
    pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
    __msg msg;
    msg.fd_r = open("1.png", O_RDONLY);
    msg.fd_w = open("2.png", O_WRONLY|O_CREAT|O_TRUNC, 0664);
    if(msg.fd_r < 0 || msg.fd_w < 0)
    {
        perror("open");
        return -1;
    }
    //计算大小
    msg.size = lseek(msg.fd_r, 0, SEEK_END);
    lseek(msg.fd_r, 0, SEEK_SET);
    pthread_t tid1, tid2;
    if(pthread_create(&tid1, NULL, handler1, (void*)&msg) != 0)
    {
        perror("pthread_create");
        return -1;
    }
    if(pthread_create(&tid2, NULL, handler2, (void*)&msg) != 0)
    {
        perror("pthread_create");
        return -1;
    }
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    //销毁互斥所
    pthread_mutex_destroy(&mutex);
    close(msg.fd_r);
    close(msg.fd_w);
    return 0;
}
Last modification:2021 年 04 月 08 日 19 : 27 : 32