Word怎么转图片?2026年保姆级教程:4种方法一看就会,快捷键+详细步骤
2026/5/25 13:54:58
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<pthread.h> #define THREAD_COUNT 20000 //初始化锁 static pthread_mutex_t counter_mutex=PTHREAD_MUTEX_INITIALIZER; //需要创建的多个线程 void *add_thread(void *arg) { //转换传入参数 int *p = (int *)arg; //在累加之前获取锁,保证同一时间只有一个线程对其累加 pthread_mutex_lock(&counter_mutex); (*p)++; //累加完之后 释放锁 pthread_mutex_unlock(&counter_mutex); return (void *)0; } int main(int argc, char const *argv[]) { pthread_t pid[THREAD_COUNT]; int num = 0; for (int i = 0; i < THREAD_COUNT; i++) { //创建的线程功能是传入的参数累加1 pthread_create(pid+i,NULL,add_thread,&num); } //等待所有线程执行完成 for (int i = 0; i < THREAD_COUNT; i++) { pthread_join(pid[i],NULL); } //打印最终的累加结果 printf("累加结果是%d\n",num); return 0; }makefile
race_condition_test:race_condition_test.c -$(CC) -o $@ $^ -lpthread -./$@ -rm ./$@(1)没有加写锁的情况
#include<stdio.h> #include<pthread.h> #include<unistd.h> static pthread_rwlock_t rwlock =PTHREAD_RWLOCK_INITIALIZER; int shared_data=0; void *lock_writer(void *arg) { int temp = shared_data + 1; sleep(1); shared_data = temp; printf("当前是%s,shared_data为%d\n",(char*)arg,shared_data); } void *lock_read(void *arg) { //读写锁中的读是可以由多个线程统一读取的 //获取读锁 pthread_rwlock_rdlock(&rwlock); printf("当前是%s,shared_data为%d\n",(char*)arg,shared_data); pthread_rwlock_unlock(&rwlock); } int main(int argc, char const *argv[]) { //显示初始化读写锁 pthread_rwlock_init(&rwlock,NULL); pthread_t writer1,writer2,reader1,reader2,reader3,reader4,reader5,reader6; //创建两个写线程 pthread_create(&writer1,NULL,lock_writer,"writer1"); pthread_create(&writer2,NULL,lock_writer,"writer2"); //休眠等待 sleep(3); //创建读线程 pthread_create(&reader1,NULL,lock_read,"reader1"); pthread_create(&reader2,NULL,lock_read,"reader2"); pthread_create(&reader3,NULL,lock_read,"reader3"); pthread_create(&reader4,NULL,lock_read,"reader4"); pthread_create(&reader5,NULL,lock_read,"reader5"); pthread_create(&reader6,NULL,lock_read,"reader6"); //主线程等待创建的子线程运行完成 pthread_join(writer1,NULL); pthread_join(writer2,NULL); pthread_join(reader1,NULL); pthread_join(reader2,NULL); pthread_join(reader3,NULL); pthread_join(reader4,NULL); pthread_join(reader5,NULL); pthread_join(reader6,NULL); //销毁读写锁 pthread_rwlock_destroy(&rwlock); return 0; }makefile
rwlock_test_writer_unlock:rwlock_test_writer_unlock.c -$(CC) -o $@ $^ -lpthread -./$@ -rm ./$@结果
(2)加上写锁
#include<stdio.h> #include<pthread.h> #include<unistd.h> static pthread_rwlock_t rwlock =PTHREAD_RWLOCK_INITIALIZER; int shared_data=0; void *lock_writer(void *arg) { //给多个线程写入添加写锁 //同一时间只能有一个线程获取写锁会造成两个线程顺序执行 pthread_rwlock_wrlock(&rwlock); int temp = shared_data + 1; sleep(1); shared_data = temp; printf("当前是%s,shared_data为%d\n",(char*)arg,shared_data); //写入之后释放写锁 pthread_rwlock_unlock(&rwlock); } void *lock_read(void *arg) { //读写锁中的读是可以由多个线程统一读取的 //获取读锁 pthread_rwlock_rdlock(&rwlock); printf("当前是%s,shared_data为%d\n",(char*)arg,shared_data); pthread_rwlock_unlock(&rwlock); } int main(int argc, char const *argv[]) { //显示初始化读写锁 pthread_rwlock_init(&rwlock,NULL); pthread_t writer1,writer2,reader1,reader2,reader3,reader4,reader5,reader6; //创建两个写线程 pthread_create(&writer1,NULL,lock_writer,"writer1"); pthread_create(&writer2,NULL,lock_writer,"writer2"); //休眠等待 sleep(3); //创建读线程 pthread_create(&reader1,NULL,lock_read,"reader1"); pthread_create(&reader2,NULL,lock_read,"reader2"); pthread_create(&reader3,NULL,lock_read,"reader3"); pthread_create(&reader4,NULL,lock_read,"reader4"); pthread_create(&reader5,NULL,lock_read,"reader5"); pthread_create(&reader6,NULL,lock_read,"reader6"); //主线程等待创建的子线程运行完成 pthread_join(writer1,NULL); pthread_join(writer2,NULL); pthread_join(reader1,NULL); pthread_join(reader2,NULL); pthread_join(reader3,NULL); pthread_join(reader4,NULL); pthread_join(reader5,NULL); pthread_join(reader6,NULL); //销毁读写锁 pthread_rwlock_destroy(&rwlock); return 0; }makefile
rwlock_test:rwlock_test.c -$(CC) -o $@ $^ -lpthread -./$@ -rm ./$@测试用例
#include<stdio.h> #include<stdlib.h> #include<pthread.h> #define BUFFER_SIZE 5 int buffer[BUFFER_SIZE]; int count = 0; //初始化互斥锁 static pthread_mutex_t mutex =PTHREAD_MUTEX_INITIALIZER; //初始化条件变量 static pthread_cond_t condvar=PTHREAD_COND_INITIALIZER; //期望功能是读或者写的一方 一直进行读写操作 直到缓冲读完或者写满 暂时释放锁 void *producer(void * arg) { int item = 1; //使用共同的变量 使用互斥锁 首先获取锁 pthread_mutex_lock(&mutex); while (1) { //使用共同的变量 使用互斥锁 首先获取锁 //pthread_mutex_lock(&mutex); //如果缓冲区写满 使用条件变量暂停当前线程 if (count == BUFFER_SIZE) { //暂停线程 pthread_cond_wait(&condvar,&mutex); } //缓冲区没有满 buffer[count++]=item++; printf("白月光发送了一个幸运数字%d\n",buffer[count-1]); //唤醒消费者 pthread_cond_signal(&condvar); //释放锁 //pthread_mutex_unlock(&mutex); } //释放锁 pthread_mutex_unlock(&mutex); } void *consumer(void * arg) { //使用共同的变量 使用互斥锁 首先获取锁 pthread_mutex_lock(&mutex); while (1) { if (count == 0) { //缓存中没有消息可读 暂停线程 pthread_cond_wait(&condvar,&mutex); } printf("我收到白月光的幸运数字为%d\n",buffer[--count]); //通知生产者可以继续写 pthread_cond_signal(&condvar); } //释放锁 pthread_mutex_unlock(&mutex); } int main(int argc, char const *argv[]) { //创建两个线程 一个向buf中写 一个从buf中读 pthread_t producer_thread,consumer_thread; //创建生产者线程 pthread_create(&producer_thread,NULL,producer,NULL); //创建消费者线程 pthread_create(&consumer_thread,NULL,consumer,NULL); //主线程需要挂起等待两个子线程完成 pthread_join(producer_thread,NULL); pthread_join(consumer_thread,NULL); return 0; }makefile
condition_var:condition_var.c -$(CC) -o $@ $^ -lpthread -./$@ -rm ./$@使用信号量解决线程同步问题
#include<stdio.h> #include<unistd.h> #include<fcntl.h> #include<sys/mman.h> #include<sys/stat.h> #include<sys/types.h> #include<sys/wait.h> #include<semaphore.h> int main(int argc, char const *argv[]) { char *shm_value_name = "unnamed_sem_shm_value"; //创建信号量 使用共享内存创建 char *shm_sem_name="unnamed_sem_shm_sem"; //创建内存共享对象 int value_fd = shm_open(shm_value_name,O_CREAT|O_RDWR,0666); int sem_fd = shm_open(shm_sem_name,O_CREAT|O_RDWR,0666); //调整内存共享对象的大小 ftruncate(value_fd,sizeof(int)); ftruncate(sem_fd,sizeof(sem_t)); //将内存共享对象映射到共享内存区域 int *value =mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED,value_fd,0); //初始化共享变量的值 *value = 0; //将共享内存的信号信号量共享到内存区域 sem_t *sem =mmap(NULL,sizeof(sem_t),PROT_READ|PROT_WRITE,MAP_SHARED,sem_fd,0); //初始化信号量的值 sem_init(sem,1,1); int pid =fork(); if (pid < 0) { perror("fork"); } if(pid == 0) { //信号量等待 sem_wait(sem); int tmp = *value + 1; sleep(1); *value = tmp; //信号量唤醒 sem_post(sem); } else { //信号量等待 sem_wait(sem); int tmp = *value + 1; sleep(1); *value = tmp; //信号量唤醒 sem_post(sem); //等待子进程执行完毕 waitpid(pid,NULL,0); printf("this is father ,child finished\n"); printf("the final value is %d\n",*value); } //父进程执行到这里子进程已经执行完毕 销毁信号量 if (pid > 0) { if (sem_destroy(sem) == -1) { perror("sem_destroy"); } } //无论父子进程都应该解除信号量,并关闭信号量的文件描述符 if (munmap(sem,sizeof(sem_t)) == -1) { perror("munmap sem"); } if (close(sem_fd) == -1) { perror("close sem_fd"); } //无论父子进程都应该解除共享内存的映射,并关闭共享对象的文件描述符 if (munmap(value,sizeof(int)) == -1) { perror("munmap value"); } if (close(value_fd) == -1) { perror("close value_fd"); } //如果调用时别的进程仍在使用共享对象,则等待所有进程释放资源后,才会销毁相关资源 //shm_unlink只能调用一次,这里在父进程中调用shm_unlink if (pid > 0) { if (shm_unlink(shm_value_name) == -1) { perror("father shm_unlink shm_value_name"); } if (shm_unlink(shm_sem_name) == -1) { perror("father shm_unlink shm_sem_name"); } } return 0; }makefile
unnamed_sem_bin_process:unnamed_sem_bin_process.c -$(CC) -o $@ $^ -lrt -lpthread -./$@ -rm ./$@作为计数信号量用于线程间通信
#include<stdio.h> #include<unistd.h> #include<semaphore.h> #include<stdlib.h> #include<time.h> #include<pthread.h> sem_t *full; sem_t *empty; int shard_num; int rand_num() { srand(time(NULL)); return rand(); } void *producer(void *arg) { for (int i = 0; i < 5; i++) { //获取信号量 //最开始empty 为1 可以减1 正常执行 //下次再到这里 empty为0 不能减1 不能执行 sem_wait(empty); printf("\n第%d轮数据传输\n",i+1); sleep(1); shard_num=rand_num(); //释放信号量 //使full加1 此时消费者就能够获取信号量 sem_post(full); } } void *consumer(void *arg) { for (int i = 0; i < 5; i++) { //获取信号量 //最开始full为0 不能减1 卡住挂起 sem_wait(full); printf("\n第%d轮消费者读取数据\n",i+1); sleep(1); printf("接收到的数据是%d",shard_num); //释放信号量 //消费者执行一轮 释放信号empty+1 生产者就能获取信号量 sem_post(empty); } } int main(int argc, char const *argv[]) { full=malloc(sizeof(sem_t)); empty=malloc(sizeof(sem_t)); //初始化信号量 sem_init(empty,0,1); sem_init(full,0,0); //创建生产者和消费者的线程 pthread_t producer_id,consumer_id; pthread_create(&producer_id,NULL,producer,NULL); pthread_create(&consumer_id,NULL,consumer,NULL); //等待线程全部执行完成 pthread_join(producer_id,NULL); pthread_join(consumer_id,NULL); //销毁信号量 sem_destroy(full); sem_destroy(empty); return 0; }makefile
unnamed_sem_count_thread:unnamed_sem_count_thread.c -$(CC) -o $@ $^ -lrt -lpthread -./$@ -rm ./$@作为计数信号量用于进程间通信
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<pthread.h> #include<fcntl.h> #include<semaphore.h> #include<sys/mman.h> #include<sys/stat.h> #include<sys/types.h> #include<sys/wait.h> int main(int argc, char const *argv[]) { char *shm_name="unnamed_sem_shm"; //创建共享内存 int fd=shm_open(shm_name,O_RDWR|O_CREAT,0666); //调整共享内存大小 ftruncate(fd,sizeof(sem_t)); //完成映射 sem_t *sem=mmap(NULL,sizeof(sem_t),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); //初始化信号量 sem_init(sem,1,0); //创建父子进程 pid_t pid = fork(); if (pid < 0) { perror("fork"); } if (pid == 0) { //子进程 sleep(1); printf("这是子进程\n"); sem_post(sem); } else { //父进程 //子进程睡眠1s,保证父进程先执行 //sem_wait sem=0 无法减1 卡住 sem_wait(sem); printf("这是父进程\n"); waitpid(pid,NULL,0); } //回收资源 if (pid>0) { if (sem_destroy(sem) == -1) { perror("sem_destroy"); } } //父子进程都需要关闭文件描述符 if (munmap(sem,sizeof(sem)) == -1) { perror("munmap"); } if (close(fd) == -1) { perror("close"); } if (pid > 0) { if (shm_unlink(shm_name) == -1) { perror("shm_unlink"); } } return 0; }makefile
unnamed_sem_count_process:unnamed_sem_count_process.c -$(CC) -o $@ $^ -lrt -lpthread -./$@ -rm ./$@#include<stdio.h> #include<unistd.h> #include<fcntl.h> #include<sys/mman.h> #include<sys/stat.h> #include<sys/types.h> #include<sys/wait.h> #include<semaphore.h> int main(int argc, char const *argv[]) { char *shm_value_name = "/unnamed_sem_shm_value"; char* sem_name="/named_sem_shm"; //创建内存共享对象 int value_fd = shm_open(shm_value_name,O_CREAT|O_RDWR,0666); //初始化有名信号量 sem_t * sem = sem_open(sem_name,O_CREAT,0666,1); //调整内存共享对象的大小 ftruncate(value_fd,sizeof(int)); //将内存共享对象映射到共享内存区域 int *value =mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED,value_fd,0); //初始化共享变量的值 *value = 0; int pid =fork(); if (pid < 0) { perror("fork"); } if(pid == 0) { sem_wait(sem); int tmp = *value + 1; sleep(1); *value = tmp; sem_post(sem); } else { sem_wait(sem); int tmp = *value + 1; sleep(1); *value = tmp; sem_post(sem); //等待子进程执行完毕 waitpid(pid,NULL,0); printf("this is father ,child finished\n"); printf("the final value is %d\n",*value); } //无论父子进程都应该解除共享内存的映射,并关闭共享对象的文件描述符 if (munmap(value,sizeof(int)) == -1) { perror("munmap value"); } if (sem_close(sem) == -1) { perror("close sem_close"); } if (close(value_fd) == -1) { perror("close value_fd"); } //如果调用时别的进程仍在使用共享对象,则等待所有进程释放资源后,才会销毁相关资源 //shm_unlink只能调用一次,这里在父进程中调用shm_unlink if (pid > 0) { if (shm_unlink(shm_value_name) == -1) { perror("father shm_unlink shm_value_name"); } if (shm_unlink(sem_name)==-1) { perror("shm_unlink"); } } return 0; }makefile
named_sem_bin:named_sem_bin.c -$(CC) -o $@ $^ -lrt -lpthread -./$@ -rm ./$@