线程间互斥:mutex

#include <pthread.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_init (pthread_mutex_t *mutex , pthread_mutexattr_t * attr );
int pthread_mutex_destroy (pthread_mutex_t *mutex );

int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
destroy and initialize the mutex attributes object。

int pthread_mutexattr_setpshared(pthread_mutexattr_t *mattr, int pshared)
int pthread_mutexattr_getshared(pthread_mutexattr_t *mattr,int *pshared)
指定是该进程与其他进程的同步还是同一进程内不同的线程之间的同步。可以设置为PTHREAD_PROCESS_SHARE和PTHREAD_PROCESS_PRIVATE。默认是后者,表示进程内使用锁

pthread_mutexattr_settype(pthread_mutexattr_t *attr , int type)
pthread_mutexattr_gettype(pthread_mutexattr_t *attr , int *type)
PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。
PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。
PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。
PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。

int pthread_mutex_lock (pthread_mutex_t *mutex );
int pthread_mutex_trylock (pthread_mutex_t *mutex );
int pthread_mutex_unlock (pthread_mutex_t *mutex );
线程调用该函数让互斥锁上锁,如果该互斥锁已被另一个线程锁定和拥有,则调用该线程将阻塞,直到该互斥锁变为可用为止。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

/*
#include <pthread.h>

pthread_mutex_t fastmutex=PTHREAD_MUTEX_INITEALIZER;
pthread_mutex_t recmutex=PTHREAD_RECURSIVE_MUTEX_INITEALIZER_NP;
pthread_mutex_t errchkmutex=PTHREAD_ERRORCHECK_MUTEX_INITEALIZER_NP;

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);

*/

#ifndef T_DESC
#define T_DESC(x, y)   (y)
#endif

#if T_DESC("TU1", 1)

pthread_mutex_t mutex1=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2=PTHREAD_MUTEX_INITIALIZER;

void thread_1(void)  
{  
    int i;  
    for(i=0; i<10; i++)  {
        pthread_mutex_lock(&mutex1);
        printf("This is pthread_111...");  
        sleep(2);  
        printf("111.
");
        pthread_mutex_unlock(&mutex1);
        sleep(1);  
    }  
    pthread_exit(0);  
}  
  
void thread_2(void)  
{  
    int i;  
    for(i=0; i<10; i++) {
        pthread_mutex_lock(&mutex1);
        printf("This is pthread_222...");  
        sleep(2);  
        printf("222.
");
        pthread_mutex_unlock(&mutex1);
        sleep(1);  
    }  
    pthread_exit(0);  
}  

int tu1_proc(void)  
{  
    pthread_t id_1,id_2;  
    int i,ret;  

    ret = pthread_create(&id_1, NULL, (void *)thread_1, NULL);  
    if(ret != 0)  
    {  
        printf("Create pthread error!
");  
        return -1;  
    }  
    
    ret = pthread_create(&id_2, NULL, (void *)thread_2, NULL);  
    if(ret != 0)  
    {  
        printf("Create pthread error!
");  
        return -1;  
    }  

    /*等待线程结束*/  
    pthread_join(id_1, NULL);  
    pthread_join(id_2, NULL);  

    return 0;  
}  
#endif

#if T_DESC("TU2", 1)

pthread_mutex_t mutex3;

void common_proc(char *thread_name)
{
    pthread_mutex_lock(&mutex3);
    printf("This is %s.
", thread_name);  
    sleep(2);  
    printf("common_proc sleep ok.
");
    pthread_mutex_unlock(&mutex3);
}

void thread_3(void)  
{  
    int i;  
    for(i=0; i<10; i++)  {
        common_proc("thread_3");
        sleep(1);  
        common_proc("thread_3");
    }  
    pthread_exit(0);  
}  
  
void thread_4(void)  
{  
    int i;  
    for(i=0; i<10; i++) {
        common_proc("thread_4");
        sleep(1);  
    }  
    pthread_exit(0);  
}  

int tu2_proc(void)  
{  
    pthread_t id_1,id_2;  
    int i,ret;  
    pthread_mutexattr_t mutexattr;

    pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE_NP);
    pthread_mutex_init(&mutex3, &mutexattr);
    
    ret = pthread_create(&id_1, NULL, (void *)thread_3, NULL);  
    if(ret != 0)  
    {  
        printf("Create pthread error!
");  
        return -1;  
    }  
    
    ret = pthread_create(&id_2, NULL, (void *)thread_4, NULL);  
    if(ret != 0)  
    {  
        printf("Create pthread error!
");  
        return -1;  
    }  
    
    /*等待线程结束*/  
    pthread_join(id_1, NULL);  
    pthread_join(id_2, NULL);  

    return 0;  
}  

#endif

#if T_DESC("global", 1)

void usage()
{
    printf("
 Usage: <cmd> <tu> <p1> <...>");
    printf("
   1 -- NORMAL_MUTEX");
    printf("
   2 -- RECURSIVE_MUTEX");
    printf("
");
}

int main(int argc, char **argv)
{
    int ret;
    
    if(argc < 2) {
        usage();
        return 0;
    }

    int tu = atoi(argv[1]);
    if (tu == 1) ret = tu1_proc();
    if (tu == 2) ret = tu2_proc();
    
    return ret;
}
#endif
原文地址:https://www.cnblogs.com/soul-stone/p/6683145.html