这里写目录标题
5-1-1多线程编程
一、答案
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int sum1 = 0, sum2 = 0;
void *p1(){
int i, tmp = 0;
for (i = 1; i <= 100; i++)
tmp += i;
sum1 += tmp;
}
void *p2(){
int i, tmp = 0;
for (i = 101; i <= 200; i++)
tmp += i;
sum2 += tmp;
}
void p3(){
printf("sum: %d\n", sum1 + sum2);
}
int main(){
int res;
pthread_t t1, t2;
void *thread_result;
pthread_create(&t1, NULL, p1, NULL);
pthread_create(&t2, NULL, p2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
p3();
return 0;
}
二、需要注意的地方
①关于pthread_create和pthread_join函数调用
不需要有res、result等变量接收函数返回值,也不必要设置if语句处理线程创建失败等情况的处理语句(在不考虑代码健壮性的情况下)。
可以直接这样写
pthread_create(&t1, NULL, p1, NULL);
pthread_create(&t2, NULL, p2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
③关于2个线程和3个线程
2个线程不等于main函数中引用两次pthread_creat函数,而是pthread_creat函数创建的线程和原函数的线程加起来共有两个,三个线程同理。
5-1-2信号量的应用
一、答案
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define CUSTOMER_NUM 10
int customer_state[CUSTOMER_NUM] = {0};
/**********Here**********/
sem_t s;
/************************/
void sleep_random(int t) {
sleep((int)(t * (rand() / (RAND_MAX *1.0))));
}
void print_cur_state() {
int i;
printf(" customers with seats: (");
for (i = 0; i < CUSTOMER_NUM; i++)
{
if (0 != customer_state[i])
printf(" %d", i+1);
}
printf(" )\n");
}
void *customer(void *id)
{
const int myid = *(int*)id;
sleep_random(2);
printf("customer %d: try to get a seat...\n", myid);
/**********Here**********/
sem_wait(&s);
/************************/
printf("customer %d: sit down\n", myid);
customer_state[myid-1] = 1;
print_cur_state();
sleep_random(3);
/**********Here**********/
sem_post(&s);
/************************/
printf("customer %d: stand up\n", myid);
customer_state[myid-1] = 0;
print_cur_state();
}
int main()
{
int i, id[CUSTOMER_NUM], res;
pthread_t t[CUSTOMER_NUM];
srand((int)time(0));
/**********Here**********/
sem_init(&s,0,2);
/*************************/
for (i = 0; i < CUSTOMER_NUM; i++)
{
id[i] = i + 1;
pthread_create(&t[i], NULL, customer, &id[i]);
}
for (i = 0; i < CUSTOMER_NUM; i++)
{
res = pthread_join(t[i], NULL);
if (res != 0)
{
perror("failed to join thread");
exit(2);
}
}
return 0;
}
5-1-3
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
void sleep_random(int t) {
sleep((int)(t * (rand() / (RAND_MAX *1.0))));
}
void delay(){
int i = 10000000;
while (i--)
;
}
#define N 5
sem_t chopstick[N];
void *phi(void *id){ /* 'id' starts from 1 */
int i, left, right, myid = *(int*)id;
left = myid - 1;
right = (myid < N) ? myid : 0;
for (i = 0; i < 3; i++){
printf("phi #%d: start of thinking\n", myid);
/**** start *************/
if(left > right )
{
int tmp = left;
left = right;
right = tmp;
}
sem_wait(&chopstick[left]);
delay();
sem_wait(&chopstick[right]);
/**** end ***************/
printf("phi #%d: start of eating\n", myid);
sleep_random(3);
sem_post(&chopstick[left]);
sem_post(&chopstick[right]);
printf("phi #%d: end of eating\n", myid);
}
}
int main(){
int i, id[N];
pthread_t t[N];
srand((int)time(0));
for (i = 0; i < N; i++){
id[i] = i + 1;
sem_init(&chopstick[i], 0, 1);
}
for (i = 0; i < N; i++)
pthread_create(&t[i], NULL, phi, &id[i]);
for (i = 0; i < N; i++)
pthread_join(t[i], NULL);
return 0;
}
5-2-1生产者与消费者问题
一、答案
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
/**********Here**********/
#define N 8
/*************************/
#define PRODUCT_NUM 15
int buffer[N], readpos = 0, writepos = 0;
/**********Here**********/
sem_t full, empty, mutex, mutex1;
/*************************/
void sleep_random(int t) {
sleep((int)(t * (rand() / (RAND_MAX *1.0))));
}
void *produce(void * id){
int i;
for (i = 0; i < PRODUCT_NUM; i++){
sleep_random(2);
sem_wait(&empty);
/**********Here**********/
sem_wait(&mutex);
int myid = *(int *)id * 1000 + i + 1;
buffer[writepos++] = myid;
/*************************/
if (writepos >= N)
writepos = 0;
/**********Here**********/
printf("produce: %d\n", myid );
sem_post(&mutex);
/*************************/
sem_post(&full);
}
}
void *consume(void * id){
int i;
for (i = 0; i < PRODUCT_NUM; i++){
sleep_random(2);
sem_wait(&full);
/**********Here**********/
sem_wait(&mutex1);
/*************************/
printf("consume: %d\n", buffer[readpos]);
buffer[readpos++] = - 1;
if (readpos >= N)
readpos = 0;
/**********Here**********/
sem_post(&mutex1);
/*************************/
sem_post(&empty);
}
}
int main(){
/**********Here**********/
int res, i, id[6];
pthread_t pro[6];
pthread_t con[6];
/*************************/
for (i = 0; i < N; i++)
buffer[i] = - 1;
srand((int)time(0));
sem_init(&full, 0, 0);
sem_init(&empty, 0, N);
/**********Here**********/
sem_init(&mutex,0,1);
sem_init(&mutex1,0,1);
for(int i = 1; i <= 5; i++)
{
id[i] = i;
pthread_create(&pro[i], NULL, produce, &id[i]);
}
for(int i = 1; i <= 5; i++)
pthread_create(&con[i], NULL, consume, &id[i]);
for(int i = 1; i <= 5; i++)
{
pthread_join(pro[i],NULL);
pthread_join(con[i],NULL);
}
/*************************/
return 0;
}
二、需要注意的问题
①防止主线程过早结束
在主线程对每个子线程设置pthread_join,以防止主进程结束导致子进程在还未执行完前提前被杀死
②信号量数量错误
虽然produce与consum的互斥信号量共享一个输出的答案是对的,但是会导致评测显示信号量数量错误,consum与produce在设置互斥的时候,应该用不同的信号量。
③一串比较有意思的c语句
pthread_create(&pro[i], NULL, produce, &id[i]);
void *produce(void * id){
...
int myid = *(int *)id * 1000 + i + 1;
...
}
5-2-2三个并发进程
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define LIMIT 20
#define M 5
#define N 8
/************************************/
int buffer1[M], buffer2[N],readpos1 = 0, writepos1 = 0, readpos2 = 0, writepos2 = 0;
sem_t full1, empty1, full2, empty2;/*mutex1. mutex2, mutex3;*/
/************************************/
void sleep_random(int t) {
sleep((int)(t * (rand() / (RAND_MAX *1.0))));
}
void *P(){
int i;
for (i = 0; i < LIMIT; i++){
sleep_random(2);
/************************************/
sem_wait(&empty1);
buffer1[(writepos1++) % M] = i + 1;
printf("P sends: %d\n", i+1 );
sem_post(&full1);
/************************************/
}
}
void *Q(){
int i, data;
for (i = 0; i < LIMIT; i++){
sleep_random(2);
/************************************/
sem_wait(&full1);
data = buffer1[(readpos1)%M];
buffer1[(readpos1++) % M] = -1;
sem_post(&empty1);
sem_wait(&empty2);
buffer2[(writepos2++) % N] = data;
sem_post(&full2);
/************************************/
}
}
void *R(){
int i;
for (i = 0; i < LIMIT; i++){
sleep_random(2);
/************************************/
sem_wait(&full2);
printf("R receives: %d\n", buffer2[(readpos2)%N]);
buffer2[(readpos2++) % N] = -1;
sem_post(&empty2);
/************************************/
}
}
int main(){
int i;
pthread_t t1, t2;
for (i = 0; i < M; i++)
buffer1[i] = - 1;
for (i = 0; i < N; i++)
buffer2[i] = - 1;
srand((int)time(0));
/************************************/
sem_init(&full1,0,0);
sem_init(&full2,0,0);
sem_init(&empty1,0,M);
sem_init(&empty2,0,N);
/************************************/
pthread_create(&t1, NULL, P, NULL);
pthread_create(&t2, NULL, Q, NULL);
R();
pthread_join(t1,NULL);
pthread_join(t2,NULL);
return 0;
}
5-2-3理发师问题
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define SEAT_NUM 2
#define CUSTOMER_NUM 5
/**************Code HERE******************/
sem_t full1, empty1, full2, empty2;
/****************************************/
void sleep_random(int t) {
sleep((int)(t * (rand() / (RAND_MAX *1.0))));
}
void *barber()
{
while(5)
{
/**************Code HERE******************/
sem_wait(&full2);
/****************************************/
printf("barber: start cutting\n");
sleep_random(3);
printf("barber: finish cutting\n");
/**************Code HERE******************/
sem_post(&empty2);
/****************************************/
}
}
void *customer(void *id)
{
const int myid = *(int*)id;
sleep_random(2);
printf("customer %d: enter waiting-room\n", myid);
/**************Code HERE******************/
sem_wait(&empty1);
/****************************************/
printf("customer %d: sit down\n", myid);
/**************Code HERE******************/
sem_post(&full1);
sem_wait(&empty2);
sem_wait(&full1);
/****************************************/
printf("customer %d: enter cutting-room and sit down\n", myid);
/**************Code HERE******************/
sem_post(&empty1);
sem_post(&full2);
sem_wait(&empty2);
/****************************************/
printf("customer %d: bye\n", myid);
/**************Code HERE******************/
sem_post(&empty2);
/****************************************/
}
int main()
{
int i, id[CUSTOMER_NUM];
pthread_t t[CUSTOMER_NUM];
srand((int)time(0));
/****************************************/
sem_init(&full1, 0, 0);
sem_init(&empty1, 0, 2);
sem_init(&full2, 0, 0);
sem_init(&empty2, 0, 1);
/****************************************/
for (i = 0; i < CUSTOMER_NUM; i++)
{
id[i] = i + 1;
pthread_create(&t[i], NULL, customer, &id[i]);
}
barber();
for (i = 0; i < CUSTOMER_NUM; i++)
pthread_join(t[i], NULL);
return 0;
}
???
#include<stdio.h>
#include<semaphore.h>
semaphore A = 0, B = 0, C = 0, D = 0, E= 0, F = 0,mutex = 1;
void task(char letter)
{
/*处理任务A*/
if(letter == 'A')
{
A();
V(A);
}
/*处理任务B、C、E*/
P(A)
if(letter == 'B')
{
B();
V(B)
}
else if(letter == 'C')
{
C();
V(C)
}
else if(letter == 'E')
{
E();
V(E)
}
V(A)
/*处理任务D*/
P(mutex);
P(B);
P(C);
V(mutex);
if(letter == 'D')
{
D();
V(D);
}
P(mutex);
V(B);
V(C);
V(mutex);
/*处理任务F*/
P(mutex);
P(E);
P(D);
V(mutex);
if(letter == 'F')
{
F();
V(F);
}
P(mutex);
V(E);
V(D);
V(mutex);
/*处理任务G、H*/
P(F);
if(letter == 'G')
G();
if(letter == 'H')
H();
V(F)
}