这是我对信号量和线程的第一次尝试。我根据示例和网上找到的手册页构建了这段代码。我对这段代码有两个疑问。
为什么每次尝试 semctl 时都会出现总线错误(我知道这是问题的根源,因为没有打印调试行 3)以及如何防止它?
尽管删除了 semctl(),为什么我无法获得对关键部分的锁定?
我正在尝试执行以下代码:
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sem.h>
#define NUM 3
char c='a';
int semId=-1;
struct sembuf lockOperation = { 0, -1, 0};
struct sembuf unlockOperation = { 0, -1, 0};
void* PrintLetter()
{
int rc;
rc=semop(semId, &lockOperation, 1);
if(rc)
{
printf("\n Unable to lock\n");
exit(1);
}
printf("%c",c); //CRITICAL SECTION
c=c+1; //CRITICAL SECTION
rc = semop(semId, &unlockOperation, 1);
if(rc)
{
printf("\n Unable to unlock\n");
exit(1);
}
pthread_exit(NULL);
}
int main()
{
pthread_t threads[NUM];
int rc=1;
long t;
printf("debug line 1\n");
semId = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL);
if( semId == -1)
{
printf("\n Error in making the sem\n");
exit(1);
}
printf("debug line 2\n");
rc = semctl(semId, 0, SETVAL, (int)1); // Comment from here
if(rc)
{
printf("\n Unable to set val to 1\n");
exit(1);
} ////////////////////////////////// till here
printf("debug line 3\n");
for(t=0; t<NUM; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintLetter, NULL);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
sleep(3);
}
pthread_exit(NULL);
}
注意:我在建议后在代码中添加了以下内容:
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux specific) */
};
还添加了以下内容:
union semun s_u;
s_u.val=1;
将 semctl 行更改为
rc = semctl(semId, 0, SETVAL, s_u);
并进行了所有 rc 检查:
if(rc == -1)
semctl() 行仍然没有成功执行。errno 现在状态:权限被拒绝
更新:我可以使用以下更改摆脱“权限被拒绝”错误:
semId = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|0660);
现在,新问题是,我无法在控制台上打印“abc”。该程序只打印“a”并挂起。不知道为什么。
最终更新:我在解锁代码中搞砸了:我使用 -1 而不是 1 这是新代码:
struct sembuf unlockOperation = { 0, 1, 0};
我感谢大家的帮助和耐心。