目录
- 1、多线程编程
- 1.1 测试程序
- 1.2 测试结果
1、多线程编程
在Linux系统中,调度是以线程为单位的,资源分配是以进程为单位的。多进程是指多个main()函数的程序,多线程,只有1个main()函数。进程和线程是多任务操作系统中的两种不同的执行单元。它们之间的区别主要有以下几点:
-
资源占用:进程是资源分配的基本单位,每个进程都有自己的地址空间、文件描述符和其他系统资源。而线程则是进程内的执行单元,在同一进程内的所有线程共享同样的资源,比如同一地址空间和文件描述符。
-
独立性:进程是独立执行的程序,进程间通信需要通过 IPC(进程间通信)机制进行。而同一进程内的线程,彼此之间可以通过共享的地址空间和全局变量进行通信。
-
调度和切换:进程是操作系统资源调度和分配的基本单位,进程切换的开销比线程要大。线程的切换则比进程轻量级的多,开销较小。
-
安全性:由于进程拥有独立的地址空间,因此各个进程之间的数据互不影响,保证了程序的安全性。然而,由于线程共享同一地址空间,因此实现线程间的同步和互斥会有更高的挑战性,需要使用锁等机制进行保证。
1.1 测试程序
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <string.h>
/*
* int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
* thread: 指向线程标识符的指针,该标识符在创建线程时自动分配
* attr: 线程属性对象,包含线程的其他属性,如堆栈大小等。如果传入 NULL,则使用默认的线程属性。
* start_routine:线程要运行的函数的指针,该函数的参数和返回值为void*类型指针。
* arg:传递给线程函数的参数
* retval: 成功返回0;失败返回错误码
*/
static char g_recvbuf[100];
static sem_t g_sem; // 信号量
static pthread_mutex_t g_tMutex = PTHREAD_MUTEX_INITIALIZER; // 互斥量
static pthread_cond_t g_tConVar = PTHREAD_COND_INITIALIZER; // 条件变量
// 线程函数
void *my_thread_func(void *data)
{
while(1)
{
//sem_wait(&g_sem);
// 等待条件成立, 若条件不成立则释放互斥量继续等待
pthread_mutex_lock(&g_tMutex);
pthread_cond_wait(&g_tConVar, &g_tMutex);
printf("recv: %s\n",g_recvbuf);
pthread_mutex_unlock(&g_tMutex);
}
return NULL;
}
/*
* 创建接收线程
* 主线程读取标准输入,发给接收线程
*/
int main(int argc, char **argv)
{
pthread_t tid;
int iRet;
char buf[100];
sem_init(&g_sem, 0, 0);
iRet = pthread_create(&tid, NULL, my_thread_func, NULL);
if(iRet)
{
printf("pthread_create err!\n");
return -1;
}
while(1)
{
fgets(buf, 100, stdin);
pthread_mutex_lock(&g_tMutex);
memcpy(g_recvbuf, buf, 100);
pthread_cond_signal(&g_tConVar); // 通知条件成立
pthread_mutex_unlock(&g_tMutex);
//sem_post(&g_sem);
}
return 0;
}
1.2 测试结果
主要用到的编译命令
1.编译时链接pthread库
gcc -o pthread pthread.c -lpthread
2.查看运行的线程
ps -T
3.后台执行程序,程序执行后命令行还可以输入命令
./pthread &
4.kill线程
kill -9 线程号
5.查看cpu使用率占比高的程序
top 查看线程对cpu使用率
测试结果
To Be Continue …