Linux系统中在程序中使用线程实验分析
时间: 2023-12-03 14:42:50 浏览: 99
在Linux系统中,可以使用多种编程语言来实现多线程编程,如C、C++、Java等。下面以C语言为例,介绍在程序中使用线程的实验分析。
1. 创建线程
在C语言中,创建线程需要使用pthread库中的pthread_create函数。该函数原型如下:
```c
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
```
其中,thread参数是一个指向pthread_t类型的指针,用于存储新线程的标识符;attr参数是一个指向pthread_attr_t类型的指针,用于指定新线程的属性;start_routine参数是一个指向函数的指针,新线程将从这个函数开始执行;arg参数是传递给start_routine函数的参数。
示例代码如下:
```c
#include <stdio.h>
#include <pthread.h>
void *thread_func(void *arg) {
printf("Hello from thread!\n");
pthread_exit(NULL);
}
int main() {
pthread_t tid;
pthread_create(&tid, NULL, thread_func, NULL);
pthread_join(tid, NULL);
return 0;
}
```
上述代码中,创建了一个新线程,并在该线程中打印一条消息。主线程中调用了pthread_join函数,等待新线程结束后再继续执行。
2. 线程同步
在多线程编程中,线程之间的执行顺序是不确定的,可能会导致数据竞争等问题。因此,需要使用线程同步机制来保证线程之间的正确性和一致性。
常用的线程同步机制包括互斥锁、条件变量、信号量等。下面以互斥锁为例,介绍其使用方法。
互斥锁是一种用于保护共享资源的锁。当一个线程获得了互斥锁后,其他线程就无法再获得该锁,直到该线程释放锁为止。
在C语言中,可以使用pthread库中的pthread_mutex_init、pthread_mutex_lock、pthread_mutex_unlock、pthread_mutex_destroy函数来实现互斥锁。
示例代码如下:
```c
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mutex;
void *thread_func(void *arg) {
pthread_mutex_lock(&mutex);
printf("Hello from thread!\n");
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
int main() {
pthread_t tid;
pthread_mutex_init(&mutex, NULL);
pthread_create(&tid, NULL, thread_func, NULL);
pthread_mutex_lock(&mutex);
printf("Hello from main thread!\n");
pthread_mutex_unlock(&mutex);
pthread_join(tid, NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
```
上述代码中,创建了一个互斥锁,并在主线程和新线程中分别使用该锁来保护打印操作。
3. 线程池
线程池是一种多线程编程模型,它通过预先创建一定数量的线程,并将它们放在一个池中等待任务的到来。当有任务需要执行时,从池中取出一个空闲线程来执行任务,执行完任务后再放回池中。
在C语言中,可以使用pthread库和队列等数据结构来实现线程池。下面给出一个简单的线程池实现代码:
```c
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#define THREAD_NUM 5
typedef struct task_node {
void (*task_func)(void *);
void *arg;
struct task_node *next;
} TaskNode;
typedef struct thread_pool {
pthread_mutex_t mutex;
pthread_cond_t cond;
TaskNode *task_list;
pthread_t threads[THREAD_NUM];
int shutdown;
} ThreadPool;
void *thread_func(void *arg) {
ThreadPool *pool = (ThreadPool *)arg;
while (1) {
pthread_mutex_lock(&(pool->mutex));
while (pool->task_list == NULL && !pool->shutdown) {
pthread_cond_wait(&(pool->cond), &(pool->mutex));
}
if (pool->shutdown) {
pthread_mutex_unlock(&(pool->mutex));
pthread_exit(NULL);
}
TaskNode *task = pool->task_list;
pool->task_list = task->next;
pthread_mutex_unlock(&(pool->mutex));
task->task_func(task->arg);
free(task);
}
}
void thread_pool_init(ThreadPool *pool) {
pthread_mutex_init(&(pool->mutex), NULL);
pthread_cond_init(&(pool->cond), NULL);
pool->task_list = NULL;
pool->shutdown = 0;
for (int i = 0; i < THREAD_NUM; i++) {
pthread_create(&(pool->threads[i]), NULL, thread_func, (void *)pool);
}
}
void thread_pool_submit(ThreadPool *pool, void (*task_func)(void *), void *arg) {
TaskNode *task = (TaskNode *)malloc(sizeof(TaskNode));
task->task_func = task_func;
task->arg = arg;
task->next = NULL;
pthread_mutex_lock(&(pool->mutex));
if (pool->task_list == NULL) {
pool->task_list = task;
} else {
TaskNode *p = pool->task_list;
while (p->next != NULL) {
p = p->next;
}
p->next = task;
}
pthread_cond_signal(&(pool->cond));
pthread_mutex_unlock(&(pool->mutex));
}
void thread_pool_destroy(ThreadPool *pool) {
pthread_mutex_lock(&(pool->mutex));
pool->shutdown = 1;
pthread_cond_broadcast(&(pool->cond));
pthread_mutex_unlock(&(pool->mutex));
for (int i = 0; i < THREAD_NUM; i++) {
pthread_join(pool->threads[i], NULL);
}
pthread_mutex_destroy(&(pool->mutex));
pthread_cond_destroy(&(pool->cond));
}
void task_func(void *arg) {
int *num = (int *)arg;
printf("Thread %lu: %d\n", pthread_self(), *num);
}
int main() {
ThreadPool pool;
thread_pool_init(&pool);
for (int i = 0; i < 10; i++) {
int *num = (int *)malloc(sizeof(int));
*num = i;
thread_pool_submit(&pool, task_func, (void *)num);
}
thread_pool_destroy(&pool);
return 0;
}
```
上述代码中,创建了一个包含5个线程的线程池,并提交了10个任务。每个任务打印一个整数。可以看到,线程池能够自动分配任务,并在多个线程间并发执行任务。
阅读全文