1.pthread ./pthread &显示进程号
ps 查看进程号
ps -T 查看线程号
也可以进入进程的proc目录查看线程
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
static char g_buf[1000];
static sem_t g_sem;
static void *my_thread_func (void *data)
{
while (1)
{
sem_wait(&g_sem);
printf("recv: %s\n", g_buf);
}
return NULL;
}
int main(int argc, char **argv)
{
pthread_t tid;
int ret;
sem_init(&g_sem, 0, 0);
ret = pthread_create(&tid, NULL, my_thread_func, NULL);
if (ret)
{
printf("pthread_create err!\n");
return -1;
}
while (1)
{
fgets(g_buf, 1000, stdin);
sem_post(&g_sem);
}
return 0;
}
通过上述例程可以发现,多次执行该函数其次序是无序的,线程之间的竞争无法控制,通过使用信号量来使得线程顺序为可控的。 为了解决上述对临界资源的竞争问题,pthread线程引出了互斥锁来解决临界资源访问。通过对临界资源加锁来保护资源只被单个线程操作,待操作结束后解锁,其余线程才可获得操作权。
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <semaphore.h>
char getbuf[128] = {0};
static sem_t g_sem;
pthread_mutex_t mutex;
static void *WorkProduct(void *data)
{
pthread_mutex_lock(&mutex);
strcpy(getbuf, "data");
pthread_mutex_unlock(&mutex);
sem_post(&g_sem);
pthread_exit(NULL);
}
static void *WorkConsume(void *data)
{
sem_wait(&g_sem);
printf("%s\n",getbuf);
pthread_exit(NULL);
}
int main(int argc, char **argv)
{
pthread_t tid, dit;
sem_init(&g_sem, 0, 0);
pthread_mutex_init(&mutex, NULL);
pthread_create(&tid, NULL, WorkProduct, NULL);
pthread_create(&dit, NULL, WorkConsume, NULL);
pthread_join(tid,NULL);
pthread_join(dit,NULL);
return 0;
}
线程的退出与回收 线程的退出情况有三种:第一种是进程结束,进程中所有的线程也会随之结束。第二种是通过函数pthread_exit来主动的退出线程。第三种被其他线程调用pthread_cancel来被动退出。 当线程结束后,主线程可以通过函数pthread_join/pthread_tryjoin_np来回收线程的资源,并且获得线程结束后需要返回的数据。
- 线程主动退出
pthread_exit函数原型如下: 线程主动退出
#include <pthread.h>
void pthread_exit(void *retval);
pthread_exit函数为线程退出函数,在退出时候可以传递一个void*类型的数据带给主线程,若选择不传出数据,可将参数填充为NULL。
- 线程被动退出
pthread_cancel函数原型如下: 线程被动退出,其他线程使用该函数让另一个线程退出
#include <pthread.h>
int pthread_cancel(pthread_t thread);
成功:返回0 该函数传入一个tid号,会强制退出该tid所指向的线程,若成功执行会返回0。
- 线程资源回收(阻塞方式)
pthread_join函数原型如下: 线程资源回收(阻塞)
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
该函数为线程回收函数,默认状态为阻塞状态,直到成功回收线程后才返回。第一个参数为要回收线程的tid号,第二个参数为线程回收后接受线程传出的数据。
- 线程资源回收(非阻塞方式)
pthread_tryjoin_np函数原型如下: 线程资源回收(非阻塞)
#define _GNU_SOURCE
#include <pthread.h>
int pthread_tryjoin_np(pthread_t thread, void **retval);
该函数为非阻塞模式回收函数,通过返回值判断是否回收掉线程,成功回收则返回。
条件变量 条件变量时一种同步机制,用来通知其他线程条件满足了。一般是用来通知对方共享数据的状态信息,因此条件变量时结合互斥量来使用的。 创建和销毁条件变量 函数原型如下: #include <pthread.h> // 初始化条件变量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
通常为NULL
// 销毁条件变量
int pthread_cond_destroy(pthread_cond_t *cond);
这些函数成功时都返回0 等待条件变量 函数原型如下:
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
这需要结合互斥量一起使用,示例代码如下:
pthread_mutex_lock(&g_tMutex);
pthread_cond_wait(&g_tConVar, &g_tMutex);
/* 操作临界资源 */
pthread_mutex_unlock(&g_tMutex);
通知条件变量 函数原型如下:
int pthread_cond_signal(pthread_cond_t *cond);
p
thread_cond_signal函数只会唤醒一个等待cond条件变量的线程,示例代码如下:
pthread_cond_signal(&g_tConVar);
条件变量模拟信号量
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>
#define BUFSIZE 128
char data[]="This is data";
char buf[BUFSIZE]= {0};
pthread_mutex_t mutex;
pthread_cond_t cond1;
pthread_cond_t cond2;
void *WorkProduct(void *arg)
{
printf("This is product\n");
while(1)
{
pthread_mutex_lock(&mutex);
while(buf[0] != 0)
{
pthread_cond_wait(&cond2,&mutex);
}
strncpy(buf,data,sizeof(data));
pthread_cond_signal(&cond1);
pthread_mutex_unlock(&mutex);
sleep(1);
}
return NULL;
}
void *WorkConsume(void *arg)
{
printf("This is consume\n");
while(1)
{
pthread_mutex_lock(&mutex);
while( 0== buf[0])
{
pthread_cond_wait(&cond1,&mutex);
}
memset(&buf[0],0,sizeof(buf));
pthread_cond_signal(&cond2);
pthread_mutex_unlock(&mutex);
sleep(1);
}
return NULL;
}
int main()
{
pthread_t cons,prod;
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond1,NULL);
pthread_cond_init(&cond2,NULL);
pthread_create(&prod,NULL,WorkProduct,NULL);
pthread_create(&cons,NULL,WorkConsume,NULL);
pthread_join(cons,NULL);
pthread_join(prod,NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond1);
pthread_cond_destroy(&cond2);
return 0;
}
|