linux 下 pthread 使用

1. 线程与进程

线程拥有自己的栈,与主线程共享全局变量。

进程的时间调度是完全独立的,一个进程内的线程共享进程获得的时间片。


2._REENTRANT 宏

可以使库函数和 errno 变成线程可重入函数。


3. 线程基本函数

需要头文件 #include

3.1  int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); 

参数说明:   thread:指向pthread_create类型的指针,用于引用新创建的线程。  

attr:用于设置线程的属性,一般不需要特殊的属性,所以可以简单地设置为NULL。 *

(*start_routine)(void *):传递新线程所要执行的函数地址。 arg:新线程所要执行的函数的参数。  调用如果成功,则返回值是0,如果失败则返回错误代码。

3.2  void pthread_exit(void *retval); 

参数说明:  retval:返回指针,指向线程向要返回的某个对象。 4
线程通过调用pthread_exit函数终止执行,并返回一个指向某对象的指针。

注意:绝不能用它返回一个指向局部变量的指针,因为线程调用该函数后,这个局部变量就不存在了,这将引起严重的程序漏洞。 

3.3  int pthread_join(pthread_t th, void **thread_return);

参数说明:  th:将要等待的线程句柄,线程通过pthread_create返回的标识符来指定。

thread_return:一个二级指针,指向另一个指针,而后者指向线程的返回值。

主线程通过调用pthread_join来等待线程结束。

4. 线程同步

线程的同步一般用信号量和互斥量来进行,两种方法使用上差不多,只是理解上面不太一样。对于实际情况,可能选择其中一个更符合问题语义。

4.1 用信号量来同步

int sem_init(sem_t *sem, int pshared, unsigned int value);

参数说明: sem:信号量对象。  

pshared:控制信号量的类型,0表示这个信号量是当前进程的局部信号量,否则,这个信号量就可以在多个进程之间共享。

value:信号量的初始值


int sem_post(sem_t *sem);

以原子操作对信号量+1;

int sem_wait(sem_t *sem);

以原子操作对信号量-1; 如果当前信号量是0,则会等待,直到别的线程将信号量变为非0.


int sem_destory(sem_t *sem);

试图销毁信号量,如果信号量有线程在使用,则会返回错误。

用信号量同步的示例代码

void takeMoney_threadsafe(char * token)
{
        sem_wait(&sem);

        if (money <= 0)
        {
                sem_post(&sem);
                return;
        }

        printf("%s read %d", token, money);
        usleep(50);
        money--;
        printf(" left %d,\n", money);

        sem_post(&sem);
        usleep (1);
}

4.2 用互斥量来同步

互斥量使用的函数和信号量非常相似。

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t, *mutexattr);

int pthread_mutex_lock(pthread_mutex_t *mutex);

锁住代码段,当有线程持有互斥锁时,别的线程不能进入这段代码。

int pthread_mutex_unlock(pthread_mutex_t *mutex);

持有锁的线程完成工作后用unlock解锁,其他线程就可以进入这段代码。

int pthread_mutex_destory(pthread_mutex_t *mutex);

销毁互斥量。


用互斥量来同步的代码示例

void takeMoney_threadsafe(char * token)
{
        //sem_wait(&sem);

        pthread_mutex_lock(&mutex);

        if (money <= 0)
        {
                // sem_post(&sem);
                pthread_mutex_unlock(&mutex);
                return;
        }

        printf("%s read %d", token, money);
        usleep(50);
        money--;
        printf(" left %d,\n", money);

        // sem_post(&sem);
        pthread_mutex_unlock(&mutex);

        usleep (1);
}



你可能感兴趣的:(Linux)