关于Linux下C语言的多线程编程,可以看做是单CPU多任务或并发执行的模式,使用线程可以有效地提高应用程序的执行效率和利用率,对于高并发场景下的服务端应用尤为重要。下面是具体的攻略:
一、线程的创建和销毁
Linux下的多线程编程主要用到pthread库,使用pthread库需要包含< pthread.h >头文件。
-
可以使用pthread_create函数来创建一个新线程,其原型为:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
其中thread是输出参数,用于获取新线程的ID;attr通常设置为NULL,表示使用系统默认的属性;start_routine是函数指针,指向线程执行的函数入口;arg是传入start_routine函数的参数。 -
线程的销毁可以使用pthread_join函数,其原型为:
int pthread_join(pthread_t thread, void **retval);
其中thread是需要等待的线程ID;retval是线程退出时的返回值。
二、线程的同步
多线程编程中,线程间的同步和互斥非常重要,可以使用以下几种方式来实现:
-
互斥锁:使用互斥锁(mutex)可以使得多个线程互斥地访问共享资源,使用pthread库中的pthread_mutex_init、pthread_mutex_lock、pthread_mutex_unlock和pthread_mutex_destroy函数可以对互斥锁进行初始化、加锁、解锁和销毁等操作。
-
读写锁:读写锁(read-write lock)允许多个线程同时读取共享资源,但只允许一个线程对共享资源进行写操作,使用pthread库中的pthread_rwlock_init、pthread_rwlock_rdlock、pthread_rwlock_wrlock、pthread_rwlock_unlock和pthread_rwlock_destroy函数可以对读写锁进行初始化、加锁、解锁和销毁等操作。
-
条件变量:条件变量(condition variable)允许线程进入休眠状态,等待另一个线程通知该条件已经被满足,使用pthread库中的pthread_cond_init、pthread_cond_wait、pthread_cond_signal、pthread_cond_broadcast和pthread_cond_destroy函数可以对条件变量进行初始化、等待、通知、广播和销毁等操作。
三、示例说明
下面给出两个例子来说明多线程编程的应用。
1. 使用线程来实现并发处理任务
假设有一个任务队列,不断地有新的任务需要处理,可以使用一个生产者线程来不断地往任务队列中添加任务,同时使用多个消费者线程来并发地处理任务。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define NUM_THREADS 5
pthread_t threads[NUM_THREADS];
pthread_mutex_t task_mutex;
int task_queue[100];
int task_count = 0;
void* producer_thread(void *arg)
{
int i;
while (1) {
int task = rand() % 1000;
pthread_mutex_lock(&task_mutex);
task_queue[task_count++] = task;
printf("producer task %d\n", task);
pthread_mutex_unlock(&task_mutex);
sleep(1);
}
return NULL;
}
void* consumer_thread(void *arg)
{
while (1) {
printf("consumer wait for task...\n");
pthread_mutex_lock(&task_mutex);
while (task_count == 0) {
pthread_mutex_unlock(&task_mutex);
sleep(1);
pthread_mutex_lock(&task_mutex);
}
int task = task_queue[--task_count];
printf("consumer task %d\n", task);
pthread_mutex_unlock(&task_mutex);
sleep(1);
}
return NULL;
}
int main()
{
int i, rc;
pthread_mutex_init(&task_mutex, NULL);
srand(time(NULL));
for (i = 0; i < NUM_THREADS; i++) {
if (i == 0) {
rc = pthread_create(&threads[i], NULL, producer_thread, NULL);
} else {
rc = pthread_create(&threads[i], NULL, consumer_thread, NULL);
}
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
在上面的代码中,使用一个producer线程来不断地往任务队列中添加任务,使用多个consumer线程来并发地从任务队列中获取任务并处理任务,使用pthread_mutex_lock和pthread_mutex_unlock来实现任务队列的互斥访问。
2. 使用线程来提高排序算法的效率
假设有一个需要排序的数组,可以使用多个线程来并发地进行排序操作,提高排序的效率。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM_THREADS 4
#define ARRAY_SIZE 100
#define MAX_VALUE 1000
pthread_t threads[NUM_THREADS];
typedef struct {
int *data;
int start;
int end;
} sort_arg_t;
void* sort_thread(void *arg)
{
sort_arg_t *a = (sort_arg_t *)arg;
int *data = a->data;
int start = a->start;
int end = a->end;
int i, j, t;
for (i = start; i < end; i++) {
for (j = i + 1; j < end; j++) {
if (data[i] > data[j]) {
t = data[i];
data[i] = data[j];
data[j] = t;
}
}
}
return NULL;
}
void merge_array(int *data, int a, int b, int c)
{
int i = a, j = b, k = 0;
int *tmp = (int *)malloc(sizeof(int) * (c - a));
while (i < b && j < c) {
if (data[i] < data[j]) {
tmp[k++] = data[i++];
} else {
tmp[k++] = data[j++];
}
}
while (i < b) {
tmp[k++] = data[i++];
}
while (j < c) {
tmp[k++] = data[j++];
}
for (i = a, k = 0; i < c; i++, k++) {
data[i] = tmp[k];
}
free(tmp);
}
void merge_sort(int *data, int start, int end)
{
if (start + 1 < end) {
int mid = (start + end) / 2;
merge_sort(data, start, mid);
merge_sort(data, mid, end);
merge_array(data, start, mid, end);
}
}
int main()
{
int i, rc;
int data[ARRAY_SIZE];
srand(time(NULL));
for (i = 0; i < ARRAY_SIZE; i++) {
data[i] = rand() % MAX_VALUE;
}
merge_sort(data, 0, ARRAY_SIZE);
printf("sorted data:\n");
for (i = 0; i < ARRAY_SIZE; i++) {
printf("%d ", data[i]);
}
printf("\n");
sort_arg_t arg[NUM_THREADS];
for (i = 0; i < NUM_THREADS; i++) {
arg[i].data = data;
arg[i].start = i * ARRAY_SIZE / NUM_THREADS;
arg[i].end = (i + 1) * ARRAY_SIZE / NUM_THREADS;
rc = pthread_create(&threads[i], NULL, sort_thread, &arg[i]);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
for (i = 0; i < NUM_THREADS; i++) {
rc = pthread_join(threads[i], NULL);
if (rc) {
printf("ERROR; return code from pthread_join() is %d\n", rc);
exit(-1);
}
}
printf("sorted data (multi-thread):\n");
for (i = 0; i < ARRAY_SIZE; i++) {
printf("%d ", data[i]);
}
printf("\n");
return 0;
}
在上面的代码中,使用多个线程来并发地进行排序操作,先使用单线程进行对排序算法的测试,然后使用多线程的方式来进行排序操作,使用pthread_create和pthread_join来实现线程的创建和销毁操作,使用sort_arg_t结构体来传递线程的参数,使用merge_sort来进行排序操作,线程中的sort_thread函数用来对部分数据进行排序操作。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:linux下c语言的多线程编程 - Python技术站